我维护的Django网站目前使用Python 2.7,但我知道我将在几个月后将其升级到Python 3。如果我现在正在编写必须在Python 2中工作的代码,是否有Pythonic的方式编写它,以便如果我知道Python 3中的语法,它也可以在Python 3中工作而无需进行任何更改?理想情况下,我希望代码即使在升级后也可以继续工作而不更改它,但是对我而言,很容易在代码库中发现我在哪里进行了此工作,以便我有空时可以更改代码。这是我正在谈论的示例:
# Python 2 uses 'iteritems'
def log_dict(**kwargs):
for key, value in kwargs.iteritems():
log.info("{0}: {1}".format(key, value))
# Python 3 uses 'items'
def log_dict(**kwargs):
for key, value in kwargs.items():
log.info("{0}: {1}".format(key, value))
最佳答案
有official documentation建议执行此操作的方法。随着情况的变化,该文档也随着时间的推移而发生了变化,因此值得直接查阅源文件(特别是如果您在撰写此答案后的一两年内正在阅读此答案)。
还值得阅读Conservative Python 3 Porting Guide并略读Nick Coghlan的Python 3 Q&A,尤其是this section。
从2018年初的时光倒流:
future
当前的官方建议是:
pip install coverage
)pip install future
)pip install pylint
)pip install caniusepython3
)的使用pip install tox
)注意最后的建议。 Guido和另一位核心开发人员都曾大量参与领导大型团队将2.7的大型代码库移植到3.x,并发现mypy非常有用(特别是在处理bytes-vs.-unicode问题时)。实际上,这是渐进静态类型现在成为该语言的正式组成部分的很大一部分原因。
您几乎还肯定要使用2.7中提供的所有
future
语句。这是如此明显,以至于他们似乎忘记了将其排除在文档之外,但是除了使您的生活更轻松(例如,您可以编写print
函数调用)之外,futurize
和modernize
(以及six
和sixer
)也需要它。六
该文档的目标读者是在不久的将来向Python 3不可逆转的过渡。如果您打算长时间坚持使用双版本代码,则最好遵循以前的建议,这些建议主要围绕使用six而不是将来进行。六本书涵盖了两种语言之间的更多差异,并且还使您编写的代码清楚地说明了双版本,而不是在仍以2.7运行时尽可能接近Python 3。但是不利的是,您实际上在做两个端口-一个从2.7到基于六个版本的双版本代码,然后从仅3.x的六个代码到仅3.x的“ native ”代码。
2对3
最初建议的答案是使用2to3,该工具可以自动将Python 2代码转换为Python 3代码,或指导您这样做。如果您希望您的代码在这两种代码中都能工作,则需要交付Python 2代码,然后在安装时运行
2to3
以将其移植到Python3。这意味着您需要同时测试两种代码,并且通常需要对其进行修改以便仍在2.7中可以使用,但在2to3之后也可以在3.x中使用,但这并不总是很容易解决。事实证明,这对于大多数不重要的项目而言是不可行的,因此核心开发人员不再建议使用它,但是它仍然内置在Python 2.7和3.x中并获取更新。2to3上还有两个变体:sixer自动将Python 2.7代码移植为使用六个版本的双版本代码,3to2允许您为Python 3编写代码并在安装时自动移植回2.7。两者都曾一度流行,但似乎已不再使用。现代化和 future 化分别是它们的主要继任者。
对于您的具体问题,
如果您不介意2.7的性能降低,
kwargs.items()
可以同时使用。 iteritems
更改为items
。 six.iteritems(kwargs)
,它将在2.7中执行iteritems
并在3.x中执行items
。 six.viewitems(kwargs)
,它将在2.7中执行viewitems
(这与items
在3.x中的功能相同,而不仅仅是相似的功能)。 kwargs.iteritems()
更改为six.iteritems(kwargs)
。 kwargs.items()
并在安装时在2.x上自动将其转换为viewitems
。 viewitems
或items
可使您的代码仍正确键入。 关于python - 如何编写适用于Python 2和Python 3的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50079311/