美文网首页人生苦短,python首选PythonPython
1.Python入门之--Python 2.7.x 和 Pyth

1.Python入门之--Python 2.7.x 和 Pyth

作者: Michael_林 | 来源:发表于2016-12-10 08:56 被阅读69058次

    注:本文的原文地址为

    http://segmentfault.com/a/1190000000618286

    许多 Python 初学者想知道他们应该从 Python 的哪个版本开始学习。对于这个问题我的答案是 “你学习你喜欢的教程的版本,然后检查他们之间的不同。"

    但是如果你开始一个新项目,并且有选择权?我想说的是目前没有对错,只要你计划使用的库 Python 2.7.x 和 Python 3.x 双方都支持的话。尽管如此,当在编写它们中的任何一个的代码,或者是你计划移植你的项目的时候,是非常值得看看这两个主要流行的 Python 版本之间的差别的,以便避免常见的陷阱,

    章节

    使用__future__模块

    print函数

    Integer division

    Unicode

    xrange

    Raising exceptions

    Handling exceptions

    next()函数 和.next()方法

    For 循环变量和全局命名空间泄漏

    比较不可排序类型

    通过input()解析用户的输入

    返回可迭代对象,而不是列表

    更多的关于 Python 2 和 Python 3 的文章

    future模块

    Python 3.x 介绍的 一些Python 2 不兼容的关键字和特性可以通过在 Python 2 的内置__future__模块导入。如果你计划让你的代码支持 Python 3.x,建议你使用__future__模块导入。例如,如果我想要 在Python 2 中表现 Python 3.x 中的整除,我们可以通过如下导入

    from__future__importdivision

    更多的__future__模块可被导入的特性被列在下表中:

    featureoptional inmandatory ineffect

    nested_scopes2.1.0b12.2PEP 227: Statically Nested Scopes

    generators2.2.0a12.3PEP 255: Simple Generators

    division2.2.0a23.0PEP 238: Changing the Division Operator

    absolute_import2.5.0a13.0PEP 328: Imports: Multi-Line and Absolute/Relative

    with_statement2.5.0a12.6PEP 343: The “with” Statement

    print_function2.6.0a23.0PEP 3105: Make print a function

    unicode_literals2.6.0a23.0PEP 3112: Bytes literals in Python 3000

    (Source:https://docs.python.org/2/library/future.html)

    fromplatformimportpython_version

    print函数

    [跳转到章节预览]

    很琐碎,而print语法的变化可能是最广为人知的了,但是仍值得一提的是: Python 2 的print声明已经被print()函数取代了,这意味着我们必须包装我们想打印在小括号中的对象。

    Python 2 不具有额外的小括号问题。但对比一下,如果我们按照 Python 2 的方式不使用小括号调用print函数,Python 3 将抛出一个语法异常(SyntaxError)。

    Python 2

    print'Python', python_version()print'Hello, World!'print('Hello, World!')print"text", ;print'print more text on the same line'

    Python2.7.6Hello, World!Hello, World!textprintmore textonthe same line

    Python 3

    print('Python', python_version())print('Hello, World!')print("some text,", end="")print(' print more text on the same line')

    Python3.4.1Hello, World!some text,printmore textonthe same line

    print'Hello, World!'

    File"", line1print'Hello, World!'^SyntaxError: invalid syntax

    注意

    以上通过 Python 2 使用Printing "Hello, World"是非常正常的,尽管如此,如果你有多个对象在小括号中,我们将创建一个元组,因为print在 Python 2 中是一个声明,而不是一个函数调用。

    print'Python', python_version()print('a','b')print'a','b'

    Python2.7.7('a','b')a b

    整除

    [跳转到章节预览]

    如果你正在移植代码,这个变化是特别危险的。或者你在 Python 2 上执行 Python 3 的代码。因为这个整除的变化表现在它会被忽视(即它不会抛出语法异常)。

    因此,我还是倾向于使用一个float(3)/2或3/2.0代替在我的 Python 3 脚本保存在 Python 2 中的3/2的一些麻烦(并且反而过来也一样,我建议在你的 Python 2 脚本中使用from __future__ import division)

    Python 2

    print'Python', python_version()print'3 / 2 =',3/2print'3 // 2 =',3// 2print'3 / 2.0 =',3/2.0print'3 // 2.0 =',3// 2.0

    Python2.7.63/2=13// 2 = 13/2.0=1.53// 2.0 = 1.0

    Python 3

    print('Python', python_version())print('3 / 2 =',3/2)print('3 // 2 =',3// 2)print('3 / 2.0 =',3/2.0)print('3 // 2.0 =',3// 2.0)

    Python3.4.13/2=1.53// 2 = 13/2.0=1.53// 2.0 = 1.0

    Unicode

    [跳转到章节预览]

    Python 2 有ASCII str()类型,unicode()是单独的,不是 byte 类型。

    现在, 在 Python 3,我们最终有了Unicode (utf-8)字符串,以及一个字节类:byte和bytearrays。

    Python 2

    print'Python', python_version()

    Python2.7.6

    printtype(unicode('this is like a python3 str type'))

    printtype(b'byte type does not exist')

    print'they are really'+ b' the same'they are really the same

    printtype(bytearray(b'bytearray oddly does exist though'))

    Python 3

    print('Python', python_version())print('strings are now utf-8 \u03BCnico\u0394é!')Python3.4.1strings are now utf-8μnicoΔé!

    print('Python', python_version(), end="")print(' has', type(b' bytes for storing data'))Python3.4.1has

    print('and Python', python_version(), end="")print(' also has', type(bytearray(b'bytearrays')))andPython3.4.1also has

    'note that we cannot add a string' + b'bytes for data'---------------------------------------------------------------------------TypeError                                Traceback (most recentcalllast)in()----> 1 'note that we cannot add a string' + b'bytes for data'TypeError: Can't convert 'bytes' object to str implicitly

    xrange

    [跳转到章节预览]

    在 Python 2 中xrange()创建迭代对象的用法是非常流行的。比如: for 循环或者是列表/集合/字典推导式。

    这个表现十分像生成器(比如。“惰性求值”)。但是这个xrange-iterable是无穷的,意味着你可以无限遍历。

    由于它的惰性求值,如果你不得仅仅不遍历它一次,xrange()函数 比range()更快(比如 for 循环)。尽管如此,对比迭代一次,不建议你重复迭代多次,因为生成器每次都从头开始。

    在 Python 3 中,range()是像xrange()那样实现以至于一个专门的xrange()函数都不再存在(在 Python 3 中xrange()会抛出命名异常)。

    importtimeitn =10000deftest_range(n):returnforiinrange(n):passdeftest_xrange(n):foriinxrange(n):pass

    Python 2

    print'Python', python_version()print'\ntiming range()'%timeit test_range(n)print'\n\ntiming xrange()'%timeit test_xrange(n)Python2.7.6timing range()1000loops, bestof3:433µs perlooptiming xrange()1000loops, bestof3:350µs perloop

    Python 3

    print('Python', python_version())print('\ntiming range()')%timeit test_range(n)Python3.4.1timing range()1000loops, bestof3:520µs perloop

    print(xrange(10))---------------------------------------------------------------------------NameError                                Traceback (most recentcalllast)in()----> 1 print(xrange(10))NameError: name'xrange'isnotdefined

    Python 3 中的range对象的__contains__方法

    另外一件值得一提的事情就是在 Python 3 中range有一个新的__contains__方法(感谢Yuchen Ying指出了这个),__contains__方法可以加速"查找"在 Python 3.x 中显著的整数和布尔类型。

    x =10000000defval_in_range(x, val):returnvalinrange(x)defval_in_xrange(x, val):returnvalinxrange(x)print('Python', python_version())assert(val_in_range(x, x/2) ==True)assert(val_in_range(x, x//2) ==True)%timeit val_in_range(x, x/2)%timeit val_in_range(x, x//2)Python3.4.11loops, best of3:742ms per loop1000000loops, best of3:1.19µs per loop

    基于以上的timeit的结果,当它使一个整数类型,而不是浮点类型的时候,你可以看到执行查找的速度是 60000 倍快。尽管如此,因为 Python 2.x 的range或者是xrange没有一个__contains__方法,这个整数类型或者是浮点类型的查询速度不会相差太大。

    print'Python', python_version()assert(val_in_xrange(x, x/2.0) == True)assert(val_in_xrange(x, x/2) == True)assert(val_in_range(x, x/2) == True)assert(val_in_range(x, x//2) == True)%timeit val_in_xrange(x, x/2.0)%timeit val_in_xrange(x, x/2)%timeit val_in_range(x, x/2.0)%timeit val_in_range(x, x/2)Python2.7.71loops, bestof3:285ms perloop1loops, bestof3:179ms perloop1loops, bestof3:658ms perloop1loops, bestof3:556ms perloop

    下面说下__contain__方法并没有加入到 Python 2.x 中的证据:

    print('Python', python_version())range.__contains__Python3.4.1

    print 'Python', python_version()range.__contains__Python 2.7.7---------------------------------------------------------------------------AttributeError                            Traceback (most recentcalllast)in()1print'Python', python_version()----> 2 range.__contains__AttributeError:'builtin_function_or_method'object hasnoattribute'__contains__'

    print 'Python', python_version()xrange.__contains__Python 2.7.7---------------------------------------------------------------------------AttributeError                            Traceback (most recentcalllast)in()1print'Python', python_version()----> 2 xrange.__contains__AttributeError: type object'xrange'hasnoattribute'__contains__'

    **注意在 Python 2 和 Python 3 中速度的不同***

    有些猿类指出了 Python 3 的range()和 Python 2 的xrange()之间的速度不同。因为他们是用相同的方法实现的,因此期望相同的速度。尽管如此,这事实在于 Python 3 倾向于比 Python 2 运行的慢一点。

    deftest_while():i =0whilei <20000:        i +=1return

    print('Python', python_version())%timeit test_while()Python3.4.1100loops, bestof3:2.68ms perloop

    print'Python', python_version()%timeit test_while()Python2.7.61000loops, bestof3:1.72ms perloop

    Raising exceptions

    [跳转到章节预览]

    Python 2 接受新旧两种语法标记,在 Python 3 中如果我不用小括号把异常参数括起来就会阻塞(并且反过来引发一个语法异常)。

    Python 2

    print'Python', python_version()Python2.7.6

    raise IOError, "file error"---------------------------------------------------------------------------IOError                                  Traceback (most recentcalllast)in()----> 1 raise IOError, "file error"IOError: file error

    raise IOError("file error")---------------------------------------------------------------------------IOError                                  Traceback (most recentcalllast)in()----> 1 raise IOError("file error")IOError: file error

    Python 3

    print('Python', python_version())Python3.4.1

    raiseIOError,"file error"

    File"", line1raiseIOError,"file error"^SyntaxError: invalid syntaxThe proper way toraisean exceptioninPython3:

    print('Python', python_version())raise IOError("file error")Python3.4.1---------------------------------------------------------------------------OSError                                  Traceback (most recent call last)in()1print('Python', python_version())---->2raise IOError("file error")OSError: file error

    Handling exceptions

    在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用as作为关键词。

    python 2

    print'Python', python_version()try:    let_us_cause_a_NameErrorexcept NameError, err:printerr,'--> our error message'Python2.7.6name'let_us_cause_a_NameError'isnotdefined-->ourerror message

    Python 3

    print('Python', python_version())try:    let_us_cause_a_NameErrorexcept NameError as err:print(err,'--> our error message')Python3.4.1name'let_us_cause_a_NameError'isnotdefined-->ourerror message

    next() 函数 and .next() 方法

    因为next() (.next())是一个如此普通的使用函数(方法),这里有另外一个语法改变(或者是实现上改变了),值得一提的是:在 Python 2.7.5 中函数和方法你都可以使用,next()函数在 Python 3 中一直保留着(调用.next()抛出属性异常)。

    Python 2

    print'Python', python_version()my_generator = (letterforletterin'abcdefg')next(my_generator)my_generator.next()

    Python2.7.6'b'

    Python 3

    print('Python', python_version())my_generator = (letterforletterin'abcdefg')next(my_generator)

    Python3.4.1'a'

    my_generator.next()

    ---------------------------------------------------------------------------AttributeError                            Traceback (most recentcalllast)in()----> 1 my_generator.next()AttributeError:'generator'object hasnoattribute'next'

    For 循环变量和全局命名空间泄漏

    好消息:在 Python 3.x 中 for 循环变量不会再导致命名空间泄漏。

    在 Python 3.x 中做了一个改变,在What’s New In Python 3.0中有如下描述:

    "列表推导不再支持[... for var in item1, item2, ...]这样的语法。使用[... for var in (item1, item2, ...)]代替。也需要提醒的是列表推导有不同的语义:  他们关闭了在 `list()` 构造器中的生成器表达式的语法糖, 并且特别是循环控制变量不再泄漏进周围的作用范围域."

    Python 2

    print'Python', python_version()i =1print'before: i =', iprint'comprehension: ', [iforiinrange(5)]print'after: i =', iPython2.7.6before: i =1comprehension:  [0,1,2,3,4]after: i =4

    Python 3

    print('Python', python_version())i =1print('before: i =', i)print('comprehension:', [iforiinrange(5)])print('after: i =', i)Python3.4.1before: i =1comprehension: [0,1,2,3,4]after: i =1

    比较不可排序类型

    在 Python 3 中的另外一个变化就是当对不可排序类型做比较的时候,会抛出一个类型错误。

    Python 2

    print'Python', python_version()print"[1, 2] > 'foo' = ", [1,2] >'foo'print"(1, 2) > 'foo' = ", (1,2) >'foo'print"[1, 2] > (1, 2) = ", [1,2] > (1,2)Python2.7.6[1,2] >'foo'=False(1,2) >'foo'=True[1,2] > (1,2) =False

    Python 3

    print('Python', python_version())print("[1, 2] > 'foo' = ", [1,2] >'foo')print("(1, 2) > 'foo' = ", (1,2) >'foo')print("[1, 2] > (1, 2) = ", [1,2] > (1,2))Python3.4.1---------------------------------------------------------------------------TypeError                                Traceback (most recent call last)in()1print('Python', python_version())---->2print("[1, 2] > 'foo' = ", [1,2] >'foo')3print("(1, 2) > 'foo' = ", (1,2) >'foo')4print("[1, 2] > (1, 2) = ", [1,2] > (1,2))TypeError: unorderabletypes: list() > str()

    通过input()解析用户的输入

    幸运的是,在 Python 3 中已经解决了把用户的输入存储为一个str对象的问题。为了避免在 Python 2 中的读取非字符串类型的危险行为,我们不得不使用raw_input()代替。

    Python 2

    Python2.7.6[GCC4.0.1(AppleInc. build5493)] on darwinType"help","copyright","credits"or"license"formore information.>>> my_input = input('enter a number: ')enter anumber:123>>> type(my_input)>>> my_input = raw_input('enter a number: ')enter anumber:123>>> type(my_input)

    Python 3

    Python3.4.1[GCC4.2.1(AppleInc. build5577)] on darwinType"help","copyright","credits"or"license"formore information.>>> my_input = input('enter a number: ')enter anumber:123>>> type(my_input)

    返回可迭代对象,而不是列表

    如果在 xrange 章节看到的,现在在 Python 3 中一些方法和函数返回迭代对象 -- 代替 Python 2 中的列表

    因为我们通常那些遍历只有一次,我认为这个改变对节约内存很有意义。尽管如此,它也是可能的,相对于生成器 --- 如需要遍历多次。它是不那么高效的。

    而对于那些情况下,我们真正需要的是列表对象,我们可以通过list()函数简单的把迭代对象转换成一个列表。

    Python 2

    print'Python', python_version()printrange(3)printtype(range(3))Python2.7.6[0,1,2]

    Python 3

    print('Python', python_version())print(range(3))print(type(range(3)))print(list(range(3)))Python3.4.1range(0,3)[0,1,2]

    在 Python 3 中一些经常使用到的不再返回列表的函数和方法

    zip()

    map()

    filter()

    dictionary's .keys() method

    dictionary's .values() method

    dictionary's .items() method

    更多的关于 Python 2 和 Python 3 的文章

    下面是我建议后续的关于 Python 2 和 Python 3 的一些好文章。

    移植到 Python 3

    Should I use Python 2 or Python 3 for my development activity?

    What’s New In Python 3.0

    Porting to Python 3

    Porting Python 2 Code to Python 3

    How keep Python 3 moving forward

    Python 3 的拥护者和反对者

    10 awesome features of Python that you can't use because you refuse to upgrade to Python 3

    Everything you did not want to know about Unicode in Python 3

    Python 3 is killing Python

    Python 3 can revive Python

    Python 3 is fine

    2014年07月26日发布

    相关文章

      网友评论

      • a4a8e81cc7ea:都很基础,希望能发布些高级的,最近在学习python3,感谢博主!
      • Luat物联网通信模块:可以关注下Luat开源项目,基于Air200 GPRS模块(价格才12块多),基于Lua开发应用软件,超级容易上手。 完美支持mqtt,而且开发点阵LCD 的UI 非常方便,有丰富的底层库,支持中文很方便。
      • 89f15d0cf96e:苹果电脑可以装这个软件吗?
        邋了个邋遢:苹果自带python

      本文标题:1.Python入门之--Python 2.7.x 和 Pyth

      本文链接:https://www.haomeiwen.com/subject/lziymttx.html