编写尽可能接近Python3.x语法的Python2.7代码

编写尽可能接近Python3.x语法的Python2.7代码,python,python-3.x,Python,Python 3.x,因为Django还不支持Python3.x,所以我使用Python2.7。但是,我想继续,开始尽可能熟悉新的Python3.x语法。这就引出了一个问题: 编写与Python3.x尽可能兼容的Python2.7代码的最佳方法是什么 我知道运行python-3将 警告2to3无法修复的Python 3.x不兼容性 然而,我对习惯Python3.x语法感兴趣,同时仍然使用Python2.7 例如,我似乎应该在代码中使用以下导入: from __future__ import print_funct

因为Django还不支持Python3.x,所以我使用Python2.7。但是,我想继续,开始尽可能熟悉新的Python3.x语法。这就引出了一个问题:

  • 编写与Python3.x尽可能兼容的Python2.7代码的最佳方法是什么
我知道运行
python-3将

警告2to3无法修复的Python 3.x不兼容性

然而,我对习惯Python3.x语法感兴趣,同时仍然使用Python2.7

例如,我似乎应该在代码中使用以下导入:

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
从Python 3.0开始,上述四条
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

还有什么?

避免使用
range()
zip()
,而是使用
xrange()
itertools.izip()

try:
    input = raw_input
    range = xrange
except NameError:
    pass

现在很多模块都以一种允许在Python2和Python3上执行的方式被重写。事实证明,这一点都不难,在未来,放弃对Python 2的支持将非常容易

看看有助于完成此任务的模块,它以一种方便的方式封装了许多差异:

Six为 掩盖两者之间的差异 Python 2和Python 3


它的网站(当然还有代码)列出了许多实现这一点的方法。

您还需要使用新的异常语法,即不再使用

try:
     raise Exception, "Message"
except Exception, e:
     pass
相反,你应该:

try:
     raise Exception("Message")
except Exception as e:
     pass
还要确保所有二进制字符串的前缀都是b,即:

b'这是一个二进制字符串'


有关此主题的更完整的介绍,请参见

此处的许多Python IDE都有很大帮助

,例如,可以配置为检查与任何版本范围的兼容性

并报告任何严重程度的问题:


将以下代码放入
py3k.py
模块,并按如下方式导入:
从py3k导入*
。不过,您需要将它放在每个文件中,但是如果没有人再使用Python2.x,您甚至可以将它放在那里,或者您可以搜索并用空格替换导入行,然后删除该文件

try:
    from future_builtins import *
except ImportError:
    pass

try:
    input = raw_input
    range = xrange
except NameError:
    pass
以下是我的模板文件的外观:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

"""

from __future__ import division, absolute_import, \
                       print_function, unicode_literals
from utils.py3k import *  # @UnusedWildImport


#

我建议你试试看。从他们的网站:

PythonFuture是Python2和Python3之间缺少的兼容层。它允许您使用一个干净、兼容Python 3.x的代码库,以最小的开销同时支持Python 2和Python 3

它提供了未来和过去的包,其中包含Python3和Python2特性的后端口和前端口。它还附带了futurize和巴氏杀菌,自定义的基于2to3的脚本,可以帮助您轻松地转换Py2或Py3代码,以便在一个干净的Py3样式代码库中逐个模块地支持Python2和Python3

使用python future实现python 2/3兼容性的著名项目有夹层和ObsPy


使用
xrange
的问题是,Python 3中缺少它,因此相同的代码没有机会在那里运行。如果你愿意放弃
xrange
可能带来的性能优势,那么最好使用
range
,使代码更符合python 2和3compatible@Eli为什么不尝试一下(就像我的例子)让range=xrange呢?@Eli:但是通过使用xrange等,你可以在代码上运行2to3,否则,您可能会执行类似于
zip(foo)[2]
的操作,但这不会起作用,因为Python 3中的结果不是列表。@Lennart:同意2to3。这一切实际上取决于实现转换所采用的方法。这种方法的一个缺点是,如果您的程序依赖于与_future _实用程序不兼容的包,那么您的程序将失败,并且您没有太多的控制权。例如,您使用一个简单的pypi包,它有“print something”。谢谢你,这是个好问题。@Shekhar:
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。打印语句没有问题;只有顶部具有“从未来导入打印”功能的模块才能使用
print()
功能。其中一个主要问题是3中缺少
u'string'
语法。就我而言,这是一个糟糕的决定。@Marcin:它回到了3.3版本。不需要用_语句嵌套_作用域、生成器;当py3未来工作时,它们都可用。另外,zip、map、filter应该从
future\u builtins
导入……谢谢,我不知道
future\u builtins
。你所说的“py3未来工作”是什么意思?
生成器
with_语句
嵌套的_作用域
已经在2.6中了,所以它们是不必要的,因为
打印_函数
unicode_文本
在尝试导入2.5中时会抱怨……啊,刚才还注意到:来自uuu future uuu导入的
需要在每个文件中,它不会影响来自
py3k.py的其他文件
Ninja IDE()也有一个类似的模块来帮助您将代码转换为3.X。