Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python2和Python3的双重开发_Python_Python 3.x_Python 2to3 - Fatal编程技术网

Python2和Python3的双重开发

Python2和Python3的双重开发,python,python-3.x,python-2to3,Python,Python 3.x,Python 2to3,我刚刚开始一个新的Python项目,理想情况下,我希望从一开始就提供Python2和Python3支持,并且开发开销最小。我的问题是,对于全新的项目,最好的方法是什么 我遇到过运行2to3甚至3to2的项目,它们是安装脚本的一部分。这似乎是一种非常普遍的方式。然而,似乎有几种不同的方法可以做到这一点。我也遇到过 还可以尝试编写多语言Python 2/Python 3代码。尽管这似乎是一个可怕的想法,但我注意到,我最近倾向于编写与Python3代码更为惯用的代码,尽管我仍然以Python2的形式运

我刚刚开始一个新的Python项目,理想情况下,我希望从一开始就提供Python2和Python3支持,并且开发开销最小。我的问题是,对于全新的项目,最好的方法是什么

我遇到过运行2to3甚至3to2的项目,它们是安装脚本的一部分。这似乎是一种非常普遍的方式。然而,似乎有几种不同的方法可以做到这一点。我也遇到过

还可以尝试编写多语言Python 2/Python 3代码。尽管这似乎是一个可怕的想法,但我注意到,我最近倾向于编写与Python3代码更为惯用的代码,尽管我仍然以Python2的形式运行它。我有一种感觉,当这一天终于到来时,这只会帮助我自己的过渡,但对提供或至少帮助双重支持没有多大帮助

我所看到的大多数提供双重支持的项目最近都添加了Python3支持,因此我特别好奇是否有更好的方法更适合新项目,因为在新项目中,您可以一劳永逸


谢谢

选择2或3,无论哪种是您最喜欢的口味,并通过单元测试使其在这方面工作得非常好。然后确保这些测试在通过py2to3或py3to2运行后正常工作。最好维护一个版本的代码。

根据我的经验,这取决于项目的类型

如果它是一个库或非常独立的应用程序,一个常见的选择是在Python2.7中开发,尽可能避免Python3.x中不推荐的构造,并求助于自动测试来识别py2to3留下的漏洞,您必须手动修复这些漏洞

另一方面,对于现实生活中的应用程序,要随时准备好发现尚未移植到py3k的库(有时是重要的库)。大多数情况下,您将别无选择,只能将库移植到Python3,因此,如果您负担得起的话,就去吧。通常我不能,这就是为什么我不支持Python3用于此类项目的原因(但我很难编写在合适的时候更容易移植的代码)

对于unicode处理,我发现这非常有用。这个建议对Python2.x和3.x都有好处:将来自外部的每个字符串都视为字节,尽快转换为unicode,并尽可能晚地将字符串转换为字节。还有另一个非常有启发性的视频

[更新]


这是一个古老的答案到今天(2019年)为止,使用Python 2.x启动一个项目没有很好的理由,有几个令人信服的理由可以将较旧的项目移植到Python 3.7+并放弃对Python 2.x的支持

我个人的经验是,编写在Python 2和3中都能保持不变的代码更容易,而不是依赖通常无法正确翻译的2to3/3to2脚本

也许我的情况是不寻常的,因为我正在处理大量字节类型,而2to3在转换这些字节类型时有一项艰巨的任务,但是拥有一个代码库的便利性超过了在代码中进行一些黑客攻击的肮脏性

作为一个具体的例子,我的模块是对Python3的早期转换,相同的代码用于Python2.6/2.7/3.x。有4000多行代码,这是我需要的一点,以使其适用于不同的主要版本:

# For Python 2.x/ 3.x coexistence
# Yes this is very very hacky.
try:
    xrange
    for i in range(256):
        BYTE_REVERSAL_DICT[i] = chr(int("{0:08b}".format(i)[::-1], 2))
except NameError:
    for i in range(256):
        BYTE_REVERSAL_DICT[i] = bytes([int("{0:08b}".format(i)[::-1], 2)])
    from io import IOBase as file
    xrange = range
    basestring = str

好吧,这并不漂亮,但这意味着我可以用好的Python2风格编写99%的代码,并且所有的单元测试仍然通过Python3中相同的代码。这条路线并不适合每个人,但这是一个可以考虑的选项。 如果您需要对Python2.5或更早版本的支持,使用Distribute及其2to3集成通常是最好的方式。但是,如果您只需要支持Python2.6或更高版本,我会让代码在Python2和Python3下运行而不进行转换。我也会使用库来简化这一过程。

根据我的经验,最好不要使用像
six
这样的库;相反,我为每个包提供了一个
compat.py
,其中只包含了所需的代码,与之类似
six
还承担着尝试支持早已过时的Python版本的负担:事实是,如果您接受Pythons FWIW,那么生活就会轻松得多,CherryPy项目已经成功地编写了多语言代码,在2.3到3.2版本下无需转换即可工作。这是可行的,但实际上取决于您的项目正在做什么。我们也可以用库来做这件事吗?我的意思是,我们可以合并它们以实现兼容性吗?顺便说一句,我正要在2.7和3+上问同样的问题,你救了我:-这基本上是重新实现了six所做的,我认为这可以很好地用于较小的项目。如果sys.version\u info>=(3,):的话,我可能会做一些类似于
的事情。@GustavLarsson:我就是这么做的。@GustavLarsson
如果sys.version\u info>=(3,):
顺便说一句,
six
即使在2016年也做不到。
2to3
是为这个目的设计的,但通常不太可行。它的早期倡导者大多看到了它在现实世界中的工作方式,不再真正支持以这种方式使用它
3to2
实际工作的可能性更小。这是一个很好的建议(编写2.7/3.3+多语言代码),类似于,但为什么您反对使用
six
来实现
compat.py
模块?例如,在您自己的项目中使用自己独特的API重新实现
six.indexbytes(b'123',1)==50
和其他类似的东西有什么意义?@J.F.Sebastian
six
没有包含pika所需的所有compat功能。例如,它缺少一个不应被视为列表的类型
(str,bytes)
basestring
适用于Python2;用于执行Python2样式的dict.keys()
和一些其他内容的方法;可以从六行中提取的内容相当于一打或两行。我会使用元组
(six.text\u type,bytes)
。如果
from __future__ import absolute_import, division, print_function