小编典典

如何编写与Python 3.x尽可能兼容的Python 2.x?

python

有很多方法可以 在Python 2.x中包含Python 3.x功能 ,因此将来可以轻松地将Python
2.x脚本的代码转换为Python3.x。这些示例之一是用函数替换print语句print()

>>> from __future__ import print_function

是否有任何列表或资源可以给大家一些思路,使如何使Python 2.x代码尽可能接近Python 3.x?

您能否举一些其他有用的 导入或定义的 示例,这些示例可以 使Python 2.x的外观和行为更像Python 3.x

假设我们拥有最新的Python 2.x(我相信目前是2.7.2)。


阅读 204

收藏
2021-01-20

共1个答案

小编典典

我在大约5000行上进行了最后的润色,对在CPython 2 [567],CPython 3
[0123]上运行的备份程序(http://stromberg.dnsalias.org/~strombrg/backshift/)进行了重复数据删除。(3.3仍为Alpha
0),Pypy 1.7和Jython干线。我也尝试过IronPython,但这是完全不同的事情-
它没有标准库,所以没有退路。哦,它可以将Cython用于其最内层的循环或psyco-但pypy比任何一个都快,尤其是在32位系统上。

无论如何,我发现编写要在2.x和3.x上同样运行良好的代码是:

1)print(variable)在2.x和3.x上均相同。print(variable1,variable2)不会。对于2.x,print(variable)表示“评估带括号的表达式,并使用print语句打印单个结果”。对于3.x,print(variable)说“在此单一结果上调用print函数。因此,print(’abc%d%d’%(1、2))在这两种方法中均能正常工作,因为它是单值结果,并且都使用%运算符进行字符串格式化。

2)避免八进制常量。而不是写0755,而是写(7 * 64 + 5 * 8 + 5)。

3)我要使用其中的bufsock模块来执行二进制I / O。
http://stromberg.dnsalias.org/~strombrg/bufsock.html
我会os.open一个文件,并用bufsock包裹它(或在模块中使用rawio类)。在2.x上,这将返回一个编码为8位字符串的字节字符串。在3.x上,这将返回一个字节对象,其行为与小整数列表非常相似。然后,我将绕过一个或另一个,根据需要使用“
isinstance(foo,str)”进行测试以区分两者。我这样做是因为,对于备份程序,字节就是字节-
我不想弄乱编码可靠地保存数据的麻烦,并且并不是所有的编码都能很好地往返。

4)进行例外处理时,请避免使用“ as”关键字。而是使用EG:

  try:
     self.update_timestamp()
  except (OSError, IOError):
     dummy, utime_extra, dummy = sys.exc_info()
     if utime_extra.errno == errno.ENOENT:

5)在从2.x到3.x的过渡中,一堆模块被重命名。因此,尝试将其中一个导入到否则为空的模块中,如下所示:

try:
   from anydbm import *
except ImportError:
   from dbm import *

…这将单独出现在模块中,名称为EGadbm.py。然后,每当我需要键值存储时,我都会导入adbm而不是直接导入2.x或3.x所需的两个不同的东西。然后,我将除该粗短模块adbm.py之外的所有内容都设为pylint-
并且类似pylint不喜欢的东西。这个想法是要尽可能地将所有可能的pylint,除了一个小模块本身的“万事得pylint”规则之外,每个模块一个例外。

6)设置在2.x和3.x上运行的自动单元测试和系统测试,然后在至少一个2.x解释器以及至少一个3.x解释器上进行频繁测试,将大有帮助。我也经常对我的代码运行pylint,尽管只有一个pylint可以检查是否符合2.5.x要求-
我在pylint获得3.x支持之前就开始了该项目。

7)我设置了一个小的“
python2x3”模块,该模块具有一些常量和可调用对象,以简化生活:http
://stromberg.dnsalias.org/svn/python2x3/trunk/python2x3.py

8)b’‘文字在2.5中不起作用,尽管它们在2.
[67]中起作用。我没有尝试进行预处理,而是设置了一个constants_mod.py,其中包含许多在3.x中通常为b’‘文字的内容,并将它们从简单的字符串转换为2的“
bytes”类型。 .x或3.x。因此,它们在模块导入时就被转换一次,而不是在运行时反复转换。如果您定位到2。[67]
向上,也许有更好的方法,但是当我启动Pypy项目时仅与2.5兼容,而Jython仍然如此。

9)在2.x中,长整数具有L后缀。在3.x中,所有整数都是长整数。所以我只是尽量避免使用长整数常量。2.x会根据需要将整数提升为长整数,因此对于大多数情况而言,这似乎是可行的。

10)它可以帮助很多人使用一堆Python解释器进行测试。我建造了2. [567] 和3. [0123] 并将它们存放在/ usr / local /
cpython-xy /中,以便进行测试。我还将一些Pypy和Jython放在/ usr /
local中,再次进行简单测试。拥有使CPython构建自动化的脚本非常有价值。

我相信这些都是我在一个不平凡的项目中获得高度可移植的python代码库所需的全部扭曲。我上面编写的列表的一个主要遗漏是,我没有尝试使用unicode对象-
这可能是其他人更有资格评论的内容。

高温超导

2021-01-20