Python部落)组织翻译,禁止转载,欢迎转发。
这个附录包含一些Python 2和Python 3的差异,以及一些可以不用2to3转变就可以在Python 2 和 3上运行的示例代码。
这个并不是一个完整的清单,列出的仅仅是一些预定的改变,而不是一些bug修正,尽管还有一些偶然的疏漏。
apply
2to3 fixer ☑ six support ☐
在Python3中,Python2的内置函数apply已经移除,它被用来调用一个函数,但是你可以直接调用函数,所以它已经没有价值并且从Py开始就过期了,在Python 3 中也没有对应的替换函数。
buffer
2to3 fixer ☑ six support ☐
Python2的内函数buffer在Python3中被memoryview类替换,它们并不是完全兼容,所以2to3并没有改变这个函数,除非你明确指定缓冲存储修改器(buffer fixer)。
这些可以不经2to3转化运行在Python2和Python3上:
>>> import sys
>>> if > (3,):
... buffer = memoryview
>>> b = buffer("yay!".encode)
>>> len(b)
4
callable
2to3 fixer ☑ six support ☑
Python2内置函数callable在Py中被移除,但是在Py中又被重新引入。如果你需要支持Py,可以尝试使用检查并且捕获TypeError来调用该对象,以防止该函数不能调用的情形。
如果你需要在不调用callable的情况下知晓该函数是否可被调用,在Python3中有很多解决方法:
>>> def afunction:
... pass
>>> any("__call__" in kla for
... klass in type(afunction).__mro__)
True
>>> import collections
>>> isinstance(afunction, collec)
True
如果你需要代码不经过2to3转化就在Python2和Python3上运行,可以这样使用:
six模块还定义了一个在Python3下使用的callable函数。
类(Classes)
2to3 fixer ☐ six support ☐
在Python2中有“老式”和“新式”两种类(class),Python3已经将“老式”类移除。
比较
2to3 fixer ☐ six support ☐
由于失误Python2的内置函数cmp依然存在于Py之中,但是Py.1中已经被移除。
如果你要用cmp函数,你可以这样定义:
def cmp(a, b):
return (a > b) - (a < b)
要知道更多细节,请参考无序类型,__cmp__和cmp。
coerce and __coerce__
2to3 fixer ☐ six support ☐
Python3中已经被移除corece内置函数和__coerce__方法的支持。corece函数将根据Python运算操作符的强制转换规则把数字参数转化为相应的类型,这仅在早期Python版本中实现新数字类型时有效。在Python3中没有相应的替代者,强制转换应该在数字操作符的方法中实现。
字典方法(Dictionary methods)
2to3 fixer ☑ six support ☐
在Python2中,字典的iterkeys,itervalues和iteritems方法来返回迭代器,而不是列表(list)。在Python3中标准的keys, values 和items 返回字典视图(view),这个视图是一个迭代器,所以迭代器的变种方法变得没有意义并且被移除了。
如果你不使用2to3转化要支持Python2与Python3,并且必须要使用迭代器方法,你可以经由try/except来访问:
>>> d = {"key1": "value1",
... "key2": "value2",
... "key3": "value3",
... }
>>> try:
... values = d.itervalues
... except AttributeError:
... values = d.values
>>> isinstance(values, list)
False
>>> for value in values:
... print(value)
value3
value2
value1
还有,字典中的has_key方法也已经移除,现在使用in操作符来代替。
except
2to3 fixer ☑ six support ☐
在Python2中捕获异常的语法发生了变化,旧的形式:
except (Exception1, Exception2), target:
Python3中新的语法:
except (Exception1, Exception2) as target:
其他区别是target不再是一个元组(tuple),并且移除了字符串异常。2to3转化会转变除了字符串之外的所以异常。
两个语法在Py和Py上都是工作的,但是如果你需要代码不做2to3转化而运行在Python3的早期版本上时,你可以通过来得到异常对象。
>>> import sys
>>> try:
... raise Exception("Something happened")
... except Exception:
... e = [1]
... prin[0])
Something happened
异常对象(Exception Objects)
2to3 fixer ☑ six support ☐
在Python2中异常对象是可迭代和可索引的:
在Python3中你必须使用args属性,这个方法在Python2中也是工作的。
在Py中异常还引入了一个message属性,但是在Py中就过时了,所以你将来不太可能使用它。
exec
2to3 fixer ☑ six support ☑
在Python2中exec是个语句:
在Python3中exec是一个函数:
Python3没有全局和本地字典的语义在Python2中也是工作的:
如果你需要传入全局或者本地字典,你需要定义一个有两个不同实现的定制函数,一个给Python2,一个给Python3。 像通常一样,six模块包括这个称为exec_函数的完美实现。
execfile
2to3 fixer ☑ six support ☐
Python 2的execfile语句在Python3中已经被移除。作为一个替换,你可以打开文件读取内容:
exec(open(thefile).read)
这在所有的Python版本上都是支持的。
file
2to3 fixer ☐ six support ☐
在Python2里有一个file内置类型,在Python3中这被各种文件类型替换。在Python 2中你经常看到使用file(pathname)的代码,这种代码在Python3中是错误的,使用open(pathname)来在替换这个用法。
如果你需要测试类型,在Python3中你可以查看io.IOBase而不是使用file。
filter
2to3 fixer ☑ six support ☐
在Python2中,filter函数一个列表,而Python3返回一个迭代器。在有些情况下,2to3转换会在filter调用上使用一个list调用以确定结果依旧是一个列表。如果你需要代码不做2to3转换就在Python2和Python3上运行,并且你需要结果是一个列表,你也可以这么做。
导入(Imports)
2to3 fixer ☑ six support ☐
在Python2中,如果你有一个mypackage包,该包中包含一个c模块,这将覆盖标准库中的csv模块。代码import csv将把mypackage导入本地文件,这使得从标准库导入就会变得很棘手。
在Python3这一点得以改变,所以import csv将会从标准库导入。如果导入本地c文件你需要这样写 from . import csv, from csv import my_csv需要改为 from .csv import my_csv。这叫做“相关导入”(relative imports),这里有一个语法来导入更高一层的模块: from .. import cvs。
如果你不使用2to3,并且同时支持Python2 和Python3,from .和from..语法自从Py就已经支持了,还有一个from __future__ import absulute_import语句与Python3有不一样的行为。
如果你需要支持Py或者更早的版本,你需要写上包的全名,所以import csv变成了from mypkg import csv, 并且from cvs import my_csv变成了from my import my_csv。为了代码清晰和可读,如果你能写全部路径的话,我建议避免使用相关导入。
2to3 会查看你的导入是否是本地的,并且改变它们。
缩进(Indentation)
2to3 fixer ☐ six support ☐
在Python2中一个使用tab和8个空格来缩进是一样的,所以你可以在这一行用一个tab作为缩进,下一行用8个空格作为缩进。如果使用的编辑器将tab扩展为别的数目的空格(不是8个),这将会使你感到迷惑(代码看起来会很奇怪)。
在Python3中,一个tab只能等于另一个tab。这意味着当使用tab和空格的时候,每一个缩进层次必须是始终如一的。如果你有一个文件一会用tab缩进,一会用空格缩进,你将会得到一个错误——TabError:inconsistent use of tabs and spaces in indentation(在缩进中不持续使用tab和空格)。
解决方法就是去除这个不连贯性。
英文原文:
译者:pyBean
了解野狗,请点击阅读原文。