您的位置 首页 > 娱乐休闲

Python2和3差异与变通方法

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

了解野狗,请点击阅读原文。

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“Python2和3差异与变通方法”边界阅读