Python2与Python 3的对照

首发 http://www.everlose.info/notes/2013/10/31/difference-between-python3-to-python2/

这篇文章总结了一些与Python2.6比拟Python3.0中的新特征.Python3是一个不向后兼容的版本,有了许多的转变,这些关于Python开发者来讲是非常重要的,虽然多数人说Python3真正流行起来还须要一段时刻,然则Python3确切有了很大的革新,如今也是时刻来进修Python3了。在真正邃晓Python3中的一些变化今后,会发明实在Python3的变化并没有设想的那么多,主假如修复了一些令人讨厌的处所。

平常在每个发行版源码的Misc/NEWS文件中详细描述了每个微小的变化。

罕见的停滞

Print是一个函数

在Python3中print是个函数,这意味着在运用的时刻必需带上小括号,而且它是带有参数的。

old: print "The answer is", 2+2
new: print("The answer is", 2+2)  

old: print x,      # 末端加上逗号阻挠换行  
new: print(x, end="") # 运用空格来替代新的一行  

old: print >>sys.staerr, "fatal error"  
new: print ("fatal error", file=sys.stderr)  

old: print (x, y)   # 打印出元组(x, y) 
new: print((x, y))  # 同上,在python3中print(x, y)的结果是跟这差别的  

在Python3中还可以定义分隔符,运用参数sep来指定.

print("There are <", 2+5, ">possibilities", sep="")   

上面代码的结果以下:

There are <7> possibilities  

注重:

  • print()函数不支撑Python2.X中print中的“软空格”。在Python2.X中,print "A\n", "B"的结果是”A\nB\n”;而在Python3中print("A\n", "B")的结果是"A\n B\n"

  • 在刚最先运用Python3的时刻,你会发明你常常在交互形式下你照样常常运用老式的语法print x,是时刻磨炼你的手指用print(x)来庖代它啦。

  • 假如你的项目比较大,而又想升级到Python3的时刻,不必忧郁,2to3这个东西会将一切的print语句转换为print()函数。

运用Views和Iterators替代Lists

  • dict的要领dict.keys(),dict.items(),dict.values()不会再返回列表,而是返回一个易读的“views”。如许一来,像如许的语法将不再有效了:k = d.keys();k.sort(),你可以运用k = sorted(d)来替代。sorted(d)在Python2.5及今后的版本中也有效,然则Python3效力更高了。
d = {'a': 1}
d.keys()     # dict_keys(['a'])  
d.items()    # dict_items([('a', 1)])  
d.values()   # dict_values([1])  
k = d.keys(); k.sort()     # AttributeError: 'dict_keys' object has no attribute 'sort'  
  • 一样,dict.iterkeys(),dict.iteritems(),dict.itervalues()要领也不再支撑。

  • map()filter()将返回iterators。假如你真的想要获得列表,list(map(...))是一个疾速的要领,然则更好的要领是运用列表推导(尤其是原代码运用了lambda表达式的时刻),或许重写本来的代码,改成不须要运用列表。特别是map()会给函数带来副作用,准确的要领是改成运用for轮回,由于建立一个列表是非常糟蹋的事变。

  • Python3中的range()函数跟Python2.X的xrange()函数的作用是一样的,如许可以运用恣意的数字,Python3中去除了xrange()函数。

  • zip()在Python3中返回的是一个迭代器。

比较符

Python3简化了比较符。

  • 在运用比较符(<,<=,>=,>)时,当比拟较的操作数的排序是没有意义的时刻将会抛出TypeError非常,因而像1 < '',0 > None,len <= len如许的语句不再正当了。None < None也会抛出TypeError非常,而不是返回False。你应当邃晓了,胡乱的比较是没有意义的,比拟较的元素必需是可以比较的才行。须要注重的是,==!=不包括在内,由于差别范例的,没法比较元素老是不等于另一个的。

  • builtin.sortedlist.sort()不再有供应比较函数的cmp参数,只要参数keyreverse

  • cmp()函数应当当作被去除了,__cmp__()特别要领也不再支撑。在须要的时刻运用__lt__,__eg____hash__

整型数

  • 从本质上来讲,long重命名了int,由于在内置只要一个名为int的整型,但它基础跟之前的long一样。

  • 1/2如许的语句将返回float,即0.5。运用1//2来猎取整型,这也是之前版本所谓的“地板除”。

  • 移除了sys.maxint,由于整型数已没了限定。sys.maxsize可以用来当作一个比任何列表和字符串下标都要大的整型数。

  • repr()中比较大的整型数将不再带有L后缀。

  • 八进制数的字面量运用0o720替代了0720

Text Vs. Data 替代 Unicode Vs. 8-bit

Python3中转变了二进制数据和Unicode字符串。

  • Python3运用文本和(二进制)数据的理念替代之前的Unicode字符串和8-bit字符串,一切的文本默许是Unicode编码。运用str范例保留文本,运用bytes范例保留数据。当你殽杂文本和数据的时刻Python3会抛出TypeError的毛病。

  • 不能再运用u"..."字面量示意unicode文本,而必需运用b"..."字面量示意二进制数据。

  • 由于strbytes不能弄混,所以你必需显式地将他们举行转换。运用str.encode()str转换为bytes,运用bytes.decode()bytes转换为str,也可以运用bytes(s, encoding=...)str(b, encoding=...)

  • strbytes都是不可变的范例,有一个星散的可变范例的bytearray可以保留缓存的二进制数据,一切可以接收bytes的API都可以运用bytearray。这些可变的API是基于collections.MutableSequence的。

  • 移除了笼统范例basestring,运用str替代。

  • 文件默许运用文本范例翻开,这也是open()函数默许的。假如要翻开二进制文件必需运用b参数,不然会涌现毛病,而不会默默地供应毛病的数据。

  • 文件名都运用unicode字符串传入和输出。

  • 一些关于体系的API,如os.environsys.argv,当体系许可bytes而且不能一般转换为unicode的话,也会涌现问题。所以,将体系的LANG设置好是最好的做法。

  • repr()函数不再转义非ASCII字符。

  • 代码默许为UTF-8编码。

  • 移除了StringIOcStringIO。加入了io模块,并离别运用io.StringIOio.BytesIO离别用于text和data。

语法转变

新增语法

  • 函数变量和返回值annotations

  • Keyword-only变量。

  • nonlocal声明。运用nonlocal x可以直接援用一个外部作用域的变量,但不是全局变量。

  • 扩大了迭代的解包。

(a, *rest, b) = range(5)  
a   # 0
rest # [1,2,3]
b   # 4  
  • 字典推导。{k: v for k, v in stuff }
t = ((1,1), (2,2))  
d = {k: v for k, v in t}  
d     # {1: 1, 2: 2}  
  • 鸠合推导。{x for x in stuff},与set(stuff)结果一样,然则越发天真。

  • 八进制字面量0o720

  • 二进制字面量0b1010,相当于新的内置函数bin()

  • 字节字面量b或许B,相当于新的内置函数bytes()

转变的语法

  • except exc, var改成except exc as var

  • 新的元类语法。

# old  
class C:
    __metaclass__ = M
    ....  

# new  
class C(metaclass=M):  
    ....  
  • 列表推导不再支撑[... for var in item1, item2, ...],必需写成[... for var in (item1, item2,...)]

  • 省略号...作为一连表达式可以用于任何处所,之前只能用于分片中。然则必需一连写,之前带空格的. . .不再支撑。

移除的语法

  • 移除了元组的解包。不能再写def foo(a, (b, c)): ....,须要写成def foo(a, b_c):b, c = b_c

  • 移除<>,运用!=替代。

  • exec()不能再作为关键词,只能作为一个函数。而且exec()不再支撑流变量,如exec(f)需写成exec(f.read())

  • 整型不支撑l/L后缀。

  • 字符串不支撑'u/U'前缀。

  • from module import *只能用在模块级,在函数中不可运用。

  • 一切不以.最先的import语句均作为绝对路径的import看待。

  • 移除了典范类。

    原文作者:木头lbj
    原文地址: https://segmentfault.com/a/1190000000328484
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞