文章标题

来源:互联网 发布:pd11 for mac 破解版 编辑:程序博客网 时间:2024/06/06 05:08

  • 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对比如何?

两种语言核心对比点是:

对比项目 JAVA PYTHON 总结 语言类型(对变量的处理方式) 静态类型:一旦声明类型,不可动态更改 动态类型:不必声明类型,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 = 10b = "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 onefor 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 + typeif __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.codeif __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.pydef 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 threadingdef 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 threadingn = 0lock = threading.Lock()def foo():    global n    with lock:        n += 1threads = []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:        passdead_loop()

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

import threadingdef dead_loop():    while True:        passt = 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系统架构

Alt 系统架构

  • 一般网络架构从上层到下层包括: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.pyfrom flask import Flaskapp = 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
原创粉丝点击