您的位置:首页 > 编程语言 > Python开发

文章标题

2017-06-22 16:45 495 查看
Why Python

Python 安装

Python Java Side by Side基础
输出和运行

变量数值字符列表字典和赋值

代码块if条件实例

循环

文件操作

函数



模块

标准类型分类

Python高级主题
CPythonPython 解释器

多线程和锁
创建多线程

锁的使用

尴尬的锁

Python的并行

Web编程
Web系统架构

Python应用框架
Flask Django

Flask实现简单服务

参考

Why Python

本文默认有一定java基础或者深入理解java更好,首次在工作中接触python的第一个疑问就是,为什么用python,和java对比如何?

两种语言核心对比点是:

对比项目JAVAPYTHON总结
语言类型(对变量的处理方式)静态类型:一旦声明类型,不可动态更改动态类型:不必声明类型,python根据运行时的值进行类型指定,同样可以string替换一个integer。关于静态类型和动态类型相关的争论已经持续很久了,有一个比较有意思的谈话是关于 Guido van Rossum关于Python运行时、类型方面的思考 Strong versus Weak Typing。主要讨论还是集中在开发效率、运行效率和企业级应用的构建上。Python胜在原型构建速度上,java胜在运行效率和企业级应用上。
原型构建速度和系统运行效率Java运行效率更高Python的产品构架你速度更高在许多研究结论中都可以得出一个结论:Python比Java的生产效率高出两倍。(1)Python为什么会比Java构建效率高可以深入参考Python速度虽然慢,但它工作效率高啊。(2)Python运行效率为什么低,有篇好文分析的很深入why python is slow
JVM(HotSpot)和Python解释(CPython)Java现阶段比较流行的虚拟机是HotSpot(包括了一个解释器和两个编译器)Cpython解释器是实现python的其中的一个版本,也是现在官方的、最流行的版本Java和Python的实现都依托于各自的解释器和编译器。JVM虚拟机有自己很完善的架构并且在运行前进行编译成Bytecode并在运行时解释成机器语言。Cpython是在运行期间将Python解释成机器语言在效率上要慢一些
在Python支持者的观点中有一点非常好:要准确的定位到自身产品和系统的瓶颈。如今的计算机和网络,在系统的前期甚至是中后期,运行效率和伸缩复用性一般都不会成为系统的瓶颈,往往业务上的速度至关重要。

Python 安装

http://www.python.org/download/下载2.7版本的安装包

安装python

把python的安装目录添加到path系统变量中

Python & Java Side by Side基础

输出和运行

Java

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

运行:javac HelloWorld.java
java HelloWorld


Python

print 'Hello World'

运行:python HelloWorld.python


变量(数值,字符,列表,字典)和赋值

Java

Java是静态类型语言,必须制定变量类型

Integer a = 10;
String b = "abc";
List<String> c = Arrays.asList(1,2,3,4);
Map<String, String> d = new HashMap<>();
d.put("key","value");


Python

Python是动态类型语言,动态类型语言,运行期间制定类型

a = 10
b = "abc"
c = [1, 2, 3, 4]
d = {'key': 'value', 'key1': 'value1'}

print type(a)
print type(b)
print type(c)
print type(d)

输出:<type 'int'>
<type 'str'>
<type 'list'>
<type 'dict'>


代码块(if条件实例)

Java

Java中if、class、while、for、方法等都是通过“{}”大括号进行开始和结尾的,进行代码块区分

if (a == b) {
System.out.println("a equals b");
} else if (a > b){
System.out.println("a is bigger");
} else {
System.out.println("b is bigger");
}


Python

Python中的if、class、def(方法)、for等这样的复合语句以关键字开始,冒号结束。同时通过4个空格进行缩紧区分代码块

if a == b:
print "a equals b"
elif a > b:
print "a is bigger"
else:
print "b is bigger"


循环

Java

for (Integer one : a) {
System.out.println(a);
}
for (Map.Entry<String, String> entry : b.entrySet()) {
System.out.println(entry.getKey());
}


Python

for one in c:
print one

for one in d:
print one


文件操作

Java

File file = new File(filePath);
InputStream in = null;
try {
System.out.println("以字节为单位读取文件内容,一次读一个字节:");
// 一次读一个字节
in = new FileInputStream(file);
int tempbyte;
while ((tempbyte = in.read()) != -1) {
System.out.write(tempbyte);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
return;
}


Python

myFile = open(filePath)

print myFile.read()


函数

Java

public static Integer functionName(Integer a, Integer b) {
return a + b;
}

public static void main(String[] args) {
functionName(1, 2)
}


Python

python方法的命名以下划线分割

def function_name(code=None, type=None):
return code + type

if __name__ == '__main__':
r = function_name(code = 1, type = 2)
print r


Java

public class MyClass {
public Integer functionName(Integer a, Integer b) {
return a + b;
}

public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.functionName(1, 2);
}
}


Python

python并不像Java一样强制面向对象创建类,可以不进行类的创建

class MyClass(object):
def __init__(self, code=None):
self.code = code
print 'created a instance'

def show_code(self):
print self.code

if __name__ == '__main__':
my_class = MyClass(1)
my_class.show_code()


模块

python

python中的模块是将代码分成有组织的代码段,一个文件可以被看成一个独立的模块。模块的文件名就是模块的名字加上扩展名.py

>>> import mymoudle
输出:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named mymoudle


python查找模块的路径

>>> import sys
>>> sys.path

输出:
['', '/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload', '/Library/Python/2.7/site-packages', '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python', '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC']


以上输出结果就是python默认查找模块的地址,可以把自己的mymoudle放到当前目录就可以进行import

mymoudle.py

def sum(a, b):
print a + b

>>> import mymoudle
>>> mymoudle.my_sum(1, 2)
3


标准类型分类

Python标准类型可以分为:数值、字符串、列表、元组合字典

按照存储模型分类(能存储多少对象)

分类Python 类型
原子类型数值、字符串
容器类型列表、元组、字典
* 按照更新类型分类(对象创建后它的值是否可以改变)

分类Python 类型
不可变类型数值、字符串
可变类型列表、元组、字典
“`

a = 1

id(a)

140718964233288

a = 2

id(a)

140718964233264

str = ‘xxxx’

id(str)

4459015312

str = ‘aaaa’

id(str)

4459015504

既然a可以被重新赋值,那为什么说是不可变类型。原因就像输出一样,实际是新创建了一个对象,而不是修改原有对象的值

“`

“`

alist = [1, 2, 3]

alist[2]

3

id(alist)

4458858400

alist[2] = alist[2] + 1

alist

[1, 2, 4]

id(alist)

4458858400

对象的值可以进行修改

“`

“`

a=256

b=256

id(a)

140718964239024

id(b)

140718964239024

a=257

b=257

id(a)

140718964266976

id(b)

140718964267072

Python和Java一样会对常用的int数值进行缓存。Python缓存到256

“`



综上:在方法中修改不可变类型的参数时,方法外并不会体现**

Python高级主题

CPython(Python 解释器)

一说到编译器和解释器,Java虚拟机总是有很多说不完的话题如内存模型、垃圾回收、类加载和优化等,但是Python的解释器CPython甚至在许多Python的书中没有一个小节去介绍。

多线程和锁

创建多线程

import threading

def thread_my():
thread = threading.current_thread()
print 'thread name --'
print thread.getName()

t = threading.Thread(target=thread_my)
t.start()

thread_my()
t.join()


锁的使用

经典的 n += 1问题看看Python用锁怎么处理

import threading

n = 0
lock = threading.Lock()

def foo():
global n
with lock:
n += 1

threads = []
for i in range(100):
t = threading.Thread(target=foo)
threads.append(t)

for t in threads:
t.start()

for t in threads:
t.join()

print(n)


尴尬的锁

线程和锁在原生Python中概念非常弱化甚至有些不友好。基本上源于CPython的全局解释器锁(GIL),它的设计目的是保证同一时刻只能有一个线程在运行。在IO比较密集的任务的单核机器略显吃力。

static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */


上面是Cpython的 ceval.c的一段源码,解释器中所有代码执行的时候都需要保持这个锁。

那么这个锁什么时候释放那?

一个线程无论何时开始睡眠或等待网络 I/O其他线程总有机会获取 GIL 执行 Python 代码,这是协同式多任务处理

如果一个线程不间断地在 Python 2 中运行 1000 字节码指令,或者不间断地在 Python 3 运行15 毫秒,那么它便会放弃 GIL,这是抢占式多任务处理

可以把Python想象成2000年单核cpu的年代的机器,多个任务抢占一个cpu,而Python是多个线程抢占一个GIL

为什么说原生Python在多核任务中略显吃力

def dead_loop():
while True:
pass

dead_loop()


上面这段代码如果跑在双核cpu的机器上,会发现只是占用50%的cpu。那按照Java的思路如何跑满两个核,ok再创建一个线程继续跑

import threading

def dead_loop():
while True:
pass

t = threading.Thread(target=dead_loop)
t.start()

dead_loop()

t.join()


但是问题出现了,效果还是只有50%的占用率,并没有跑满两个核,这里面的原因就是因为GIL。为什么Python作者这么设计,Python中没有去掉GIL。去掉全局锁必然会带来细粒度的锁或者Lock-free模式,在1999年做过一个分支去掉了GIL,但是在测试过程中发现单线程的效率降低了两倍,并且随着cpu的增加效率的提升并不是线性的,而是非常缓慢,可以看下开发者的Greg’s写的信 Gregs Free threading

Python的并行

因为存在着GIL,导致Python的线程不能实现真正意义上的并行,但是也并不是没有办法处理

采用多进程处理,这样失去了线程间的共享变量和通信的便利了

通过ctypes引入c代码来实现真正意义上的并行

Web编程

Web系统架构



一般网络架构从上层到下层包括:DNS服务器->LVS服务器->应用容器->应用系统

在开发过程中只需要关注应用容器和应用系统就好,在Java中应用容器有Resin、Tomcat、Jetty等。应用系统框架有EJB、Spring、Struts等

Python中应用系统框架有Django、Flask、Tornado。Python中没有容器的概念,但是大同小异Python把容器拆成公共规范(WSGI)和中间件,而公共规范和中间件加一起所做的事情又非常类似Java中的容器(servlet容器和连接器)。servlet容器约定了调用service()方法,应用框架或者程序需要实现servie(),连接器负责包装request和response给servlet容器。同样的WSGI里面预定了相应的应用框架和程序需要时间的方法,而中间件负责将request和response进行封装

WSGI 的全称是Web Server Gateway Interface,他是一个规范。它所做的事情和servlet类似,让应用程序可以很方便的在各种应用容器上进行迁移,不必因为用了某个特定容器而使用指定的应用框架,也不必因为用了某个特定框架而实用指定容器。想要深入了解可以看下PEP333。还有中文介绍理解WSGI

Python应用框架

Instagram是Python的重度依赖用户,Instagram 的总注册用户达到 30 亿,月活用户超过 7 亿 (作为对比,微信最新披露的月活跃用户为 9.38 亿)。而令人吃惊的是,这么高的访问量背后,竟完全是由以速度慢著称的 Python + Django 支撑

Flask & Django

业界比较成熟的两个框架,有一篇关于两者对比的文章Flask VS Django,主要阐述了Flask小而灵活,只包含了必要的模块。而Django大而全,比较臃肿,会默认引入许多模块

Flask实现简单服务

安装pip(官网标准http://flask.pocoo.org/docs/0.12/installation/#installation)
windows步骤:
(1)下载https://bootstrap.pypa.io/get-pip.py
(2)执行python get-pip.py install
(3)将Python27\Scripts加入到环境变量
(4)pip install Flask
(5)创建hello.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

$ set FLASK_APP=hello.py
$ flask run

访问http://127.0.0.1:5000/


参考

Python & Java: A Side-by-Side Comparison

Python速度虽然慢,但它工作效率高啊

Strong versus Weak Typing(A Conversation with Guido van Rossum)

Python&Java细节对比

Why python is slow

理解WSGI

Instagram使用Python经验

python线程GIL和ctypes

Greg`s Free threading
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息