我正在努力使我的一些代码Python 2和3兼容。
目前,我正在努力处理range
/ xrange
等功能以及dict.items
/ dict.iteritems
等方法。理想情况下,我希望我的代码能够在Python 3.x中使用前者,在Python 2.x中使用后者。
在我看来,使用if
/ else
是实现此目标的最简单方法:
if py >= 3:
for item in array.items()
...
else:
for item in array.iteritems()
然而,这样做会导致大量重复和丑陋的代码。是否有更好的方法仅使用标准库?如果range
和dict.items
/ py >= 3
,我可以在代码开头的某个地方声明始终使用xrange
/ dict.iteritems
如果没有?
是否可以做这样的事情?
if py < 3:
use xrange as range
我环顾四周,我知道有几个图书馆,比如六个图书馆,用来解决这个问题。但是我正在使用只运行python 2.7的服务器,我不允许在其上安装任何额外的库。我有一些我想使用的python3代码,但我也想只维护一个版本的代码。
答案 0 :(得分:9)
简单,&#34;不要让我思考!&#34;我使用的解决方案是使用以下命令启动简单脚本:
#!/usr/bin/env python
# just make sure that Python 3 code runs fine with 2.7+ too ~98% of the time :)
from __future__ import (division, print_function, absolute_import,
unicode_literals)
from builtins import int
try:
from future_builtins import ascii, filter, hex, map, oct, zip
except:
pass
import sys
if sys.version_info.major > 2:
xrange = range
(额外提示阻止大多数pep8短裤因为不必要地对你大喊大叫:在上方try
区块的内部和顶部移动最后3行
但是我使用它的唯一情况基本上是#34; shell脚本太大而且毛茸茸所以我很快将它们重写为Python,我只是希望它们在Python 2下运行3有0依赖&#34;。 请不要在实际的应用程序/库代码中使用它,直到您知道完全上述所有行的后果,以及它们是否足以满足您的使用情况。< / p>
此外,&#34;解决方案&#34;在这种情况下,.iteritems
是&#34;只是不使用它&#34;,忽略内存使用优化,而始终使用.items
代替 - 如果这样重要的是,这意味着你不会写一个&#34; 0依赖简单脚本&#34;所以,只需选择Python 3和代码(如果你需要假装我们在2008年的话,就选择Python 2)。
另外,请检查这些资源以获得正确的理解:
(注意:我回答这个已经回答的问题主要是因为接受的答案大致翻译为&#34;你是愚蠢的,这是愚蠢的&#34;我发现这个<对于一个SO答案来说,非常粗鲁:无论问题多么愚蠢,以及如何错误地实际回答它,一个问题都值得一个真正的答案._
答案 1 :(得分:8)
import sys
if sys.version_info.major > 2:
xrange = range
但正如Wim所暗示的那样,基本自己重写six。
正如你可以see,six
处理range
的工作要多得多。只是例如查看六个源代码中的_moved_attributes
列表。
虽然Python附带&#34;电池包括&#34;,但它的标准库不是也不能包罗万象。它也没有缺陷。
有时会有更好的电池,不使用它们会浪费。只需将urllib2
与requests
进行比较即可。后者更好可以使用。
答案 2 :(得分:3)
我建议在项目的模块中编写py2或py3,但不能将它们混合在一起,根本不包括任何类型的2/3检查。你的程序逻辑不应该关心它的python版本,除非是为了避免内置对象上的冲突函数。
相反,从您自己的兼容层导入*,修复框架之间的差异并使用阴影,使其对您的实际项目模块透明。
例如,在兼容性模块中,您可以为范围/ xrange编写Roland Smith的替代,并在其他模块中添加&#34;来自兼容性导入*&#34;。这样做,每个模块都可以使用&#34; xrange&#34;兼容层将管理2/3的差异。
不幸的是,它不能解决现有的对象函数,例如dict.iteritems;通常你会修补dict方法,但在内置类型上是不可能的(参见https://stackoverflow.com/a/192857/1741414)。我可以想象一些解决方法:
for key in my_dict: value = my_dict[key] # rest of code goes here
答案 3 :(得分:1)
我猜你在这种情况下混淆了array
和dict
。
如果您出于任何原因限制使用三维派对库,那么为什么不喜欢这样:
def iterate_items(to_iterate):
if py >= 3:
return to_iterate.items()
else:
return to_iterate.iteritems()
然后使用它:
for item in iterate_items(your_dict):
...
答案 4 :(得分:-1)
import sys
VERSION = float("{}.{}".format(sys.version_info.major, sys.version_info.minor))
使用此代码,我们可以为所需版本编写条件代码。
if VERSION >= 3.5:
from subprocess import run as _run
else:
from subprocess import call as _run