编写尽可能接近Python 3.x语法的Python 2.7代码

Mat*_*kin 48 python python-3.x

由于Django还不支持Python 3.x,我使用的是Python 2.7.但是,我想继续并尽可能熟悉新的Python 3.x语法.这引出了我的问题:

  • 编写与Python 3.x尽可能兼容的Python 2.7代码的最佳方法是什么?

我知道跑步python -3

警告2to3无法轻易解决的Python 3.x不兼容问题.

但是,我仍然对使用Python 2.7时习惯Python 3.x语法感兴趣.

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

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
Run Code Online (Sandbox Code Playgroud)

__future__ importPython 3.0开始,上述四个语句是必需的,但在Python 2.7.3的文档27.11中描述的2.7中不需要.未来声明定义

还有什么?

Eli*_*sky 19

现在许多模块都以允许在Python 2和Python 3上执行的方式进行重写.事实证明这并不是很难,并且将来很容易放弃Python 2支持.

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

Six提供了简单的实用程序,用于包装Python 2和Python 3之间的差异.

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


Jos*_*hua 10

将下面的代码放到一个py3k.py模块并导入这样的: from py3k import *.你需要把它放在每个文件中,但如果没有人再使用Python 2.x你甚至可以把它放在那里,或者你可以用空格搜索并替换导入行然后删除文件.

try:
    from future_builtins import *
except ImportError:
    pass

try:
    input = raw_input
    range = xrange
except NameError:
    pass
Run Code Online (Sandbox Code Playgroud)

这就是我的模板文件的外观:

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

"""

"""

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


#
Run Code Online (Sandbox Code Playgroud)


Len*_*bro 8

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

try:
     raise Exception, "Message"
except Exception, e:
     pass
Run Code Online (Sandbox Code Playgroud)

相反,你应该这样做:

try:
     raise Exception("Message")
except Exception as e:
     pass
Run Code Online (Sandbox Code Playgroud)

还要确保在所有二进制字符串前加上ab,即:

这是一个二进制字符串'

有关此主题的更完整的介绍,请参阅http://python3porting.com/noconv.html

  • @Marcin:回到3.3. (3认同)

oro*_*ome 8

许多Python IDE在这里都有很大的帮助.

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

在此输入图像描述

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

在此输入图像描述


Jak*_*yer 6

try:
    input = raw_input
    range = xrange
except NameError:
    pass
Run Code Online (Sandbox Code Playgroud)

有两个让人想起......


Ign*_*ams 1

避免使用range()and zip(),而使用xrange()anditertools.izip()代替。

  • 使用“xrange”的问题是它在 Python 3 中缺失,因此相同的代码没有机会在那里运行。如果愿意放弃 `xrange` 可能带来的性能优势,最好使用 `range` 来代替,使代码更兼容 python 2 *和* 3 (5认同)
  • @Eli:但是通过使用 xrange 等,你可以在代码上简单地运行 2to3 ,否则你可能会做像 `zip(foo)[2]` 这样的事情,这是行不通的,因为 Python 3 中的结果不是列表。 (3认同)
  • @Lennart:同意 2to3。这实际上完全取决于实施转变所采取的方法。 (2认同)