我试图让我的一些代码,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
我环顾四周,我知道那几个库,例如六点futurize)被用来解决这个问题。但是我的工作仅运行Python 2.7版的服务器上,我不能在上面安装任何额外的库。我有一些python3代码,我想用,但我也想保持只有一个版本的代码。
简单,“不要让我想想!”解决办法我用的是开始简单的脚本有:
#!/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棉短绒在你不必要喊这样的:移动最后3行内和在高于try
块的顶部)
但是我用这唯一的情况下,基本上是“那是太大,多毛,所以我很快改写了他们的Python,我只是希望他们既Python 2和3 0依赖下运行shell脚本”。请直到你知道什么是最重要的行的后果,如果他们有足够为您的使用情况下,不要在真正的应用程序/库代码中使用此。
此外,“办法”在这种情况下.iteritems
“只是不使用它”,忽略了内存使用的优化,只是始终使用.items
而不是 - 如果此问题,它意味着你不是在写一个“0依赖简单的脚本”了,所以只挑的Python 3和代码它(或Python 2,如果你需要假装我们是在2008年)。
此外,检查这些资源得到一个正确的认识:
(注:我回答这个已经回答了问题,主要是因为接受的答案大致翻译为“你是愚蠢的,这是愚蠢的”,我觉得这对于一个非常粗鲁的SO回答:无论多么愚蠢的问题,以及如何“错“实际上回答这个问题,一个问题值得一个真正的answer._
我建议写在你的项目的模块PY2或PY3,而不是它们混合在一起,并没有包括任何种类的2/3检查的。你的程序的逻辑不应该有可能关心其Python版本,除了避免对内置对象发生冲突的功能。
取而代之的是,从你自己的兼容层导入*能解决你的框架和利用之间的差异阴影,使之透明,以你的实际项目中的模块。
例如,兼容性模块中,你可以写罗兰·斯密的范围/ x范围substition,并在其他模块你“从兼容性进口*”添加。这样,每一个模块可以使用“x范围”和兼容层将管理2/3的差异。
不幸的是它不会解决现有对象的功能,如dict.iteritems;通常你会猴子修补字典方法,但它是不可能在内建类型(见https://stackoverflow.com/a/192857/1741414)。我可以想像一些解决方法:
for key in my_dict: value = my_dict[key] # rest of code goes here
我猜你是array
和dict
混淆在这种情况下。
如果您在使用3-d党库,以任何理由,那么为什么不喜欢这样的限制:
def iterate_items(to_iterate):
if py >= 3:
return to_iterate.items()
else:
return to_iterate.iteritems()
然后用它:
for item in iterate_items(your_dict):
...
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