首发 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 "A\n", "B"
的结果是”A\nB\n”;而在Python3中print("A\n", "B")
的结果是"A\n B\n"
。在刚最先运用Python3的时刻,你会发明你常常在交互形式下你照样常常运用老式的语法
print x
,是时刻磨炼你的手指用print(x)
来庖代它啦。假如你的项目比较大,而又想升级到Python3的时刻,不必忧郁,
2to3
这个东西会将一切的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.sorted
和list.sort()
不再有供应比较函数的cmp参数,只要参数key
和reverse
。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"..."
字面量示意二进制数据。由于
str
和bytes
不能弄混,所以你必需显式地将他们举行转换。运用str.encode()
将str
转换为bytes
,运用bytes.decode()
将bytes
转换为str
,也可以运用bytes(s, encoding=...)
和str(b, encoding=...)
。str
和bytes
都是不可变的范例,有一个星散的可变范例的bytearray
可以保留缓存的二进制数据,一切可以接收bytes
的API都可以运用bytearray
。这些可变的API是基于collections.MutableSequence
的。移除了笼统范例
basestring
,运用str
替代。文件默许运用文本范例翻开,这也是
open()
函数默许的。假如要翻开二进制文件必需运用b
参数,不然会涌现毛病,而不会默默地供应毛病的数据。文件名都运用unicode字符串传入和输出。
一些关于体系的API,如
os.environ
和sys.argv
,当体系许可bytes
而且不能一般转换为unicode的话,也会涌现问题。所以,将体系的LANG
设置好是最好的做法。repr()
函数不再转义非ASCII字符。代码默许为UTF-8编码。
移除了
StringIO
和cStringIO
。加入了io
模块,并离别运用io.StringIO
和io.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看待。移除了典范类。