编写兼容 Python 2 和 Python 3 的代码

这篇博客提供了一种编写兼容Python 2和3的代码的方法,涵盖了安装、基本语法差异,如print函数、异常处理、除法运算、字符串和字节处理,以及字典、自定义类行为、列表迭代、内建函数和标准库的使用。作者强调了在不同Python版本间保持代码兼容性的最佳实践。
摘要由CSDN通过智能技术生成

注:本文的作者是 Ed Schofield。原文的地址为: Cheat Sheet: Writing Python 2-3 compatible code

该笔记向你展示了编写不会过时的兼容 Python 2 和 Python 3 的代码风格。

它是 Ed Schofield 在 PyCon AU 2014 的演讲,“ Writing 2/3 compatible code ”。

最低版本:

  • Python 2: 2.6+
  • Python 3: 3.3+

安装

一些下面的 imports 适用于使用 pip 安装在 PyPI 上安装:

import future        # pip install future
import past          # pip install past
import six           # pip install six

以下的脚本也适用于 pip 安装:

futurize             # pip install futurize
pasteurize           # pip install pasteurize

查看 http://python-future.org 和 https://pythonhosted.org/six/ 获取更多消息。

基本语法差异

print

# Python 2 only:
print 'Hello'
# Python 2 and 3:
print('Hello')

为了打印出多个 strings。 import print_function 来防止 Py2 把它解释成一个元组。

# Python 2 only:
print 'Hello', 'Guido'
# Python 2 and 3:
from __future__ import print_function    # (at top of module)

print('Hello', 'Guido')
# Python 2 only:
print >> sys.stderr, 'Hello'
# Python 2 and 3:
from __future__ import print_function

print('Hello', file=sys.stderr)
# Python 2 only:
print 'Hello',
# Python 2 and 3:
from __future__ import print_function

print('Hello', end='')

抛出异常

# Python 2 only:
raise ValueError, "dodgy value"
# Python 2 and 3:
raise ValueError("dodgy value")

使用 traceback 抛出异常:

# Python 2 only:
traceback = sys.exc_info()[2]
raise ValueError, "dodgy value", traceback
# Python 3 only:
raise ValueError("dodgy value").with_traceback()
# Python 2 and 3: option 1
from six import reraise as raise_
# or
from future.utils import raise_

traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)
# Python 2 and 3: option 2
from future.utils import raise_with_traceback

raise_with_traceback(ValueError("dodgy value"))

异常链 (PEP 3134):

# Setup:
class DatabaseError(Exception):
    pass
# Python 3 only
class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise DatabaseError('failed to open') from exc
# Python 2 and 3:
from future.utils import raise_from

class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise_from(DatabaseError('failed to open'), exc)
# Testing the above:
try:
    fd = FileDatabase('non_existent_file.txt')
except Exception as e:
    assert isinstance(e.__cause__, IOError)    # FileNotFoundError on Py3.3+ inherits from IOError

捕获异常

# Python 2 only:
try:
    ...
except ValueError, e:
    ...
# Python 2 and 3:
try:
    ...
except ValueError as e:
    ...

除法

整除(rounding down):

# Python 2 only:
assert 2 / 3 == 0
# Python 2 and 3:
assert 2 // 3 == 0

“True division” (float division):

# Python 3 only:
assert 3 / 2 == 1.5
# Python 2 and 3:
from __future__ import division    # (at top of module)

assert 3 / 2 == 1.5

“Old division” (i.e. compatible with Py2 behaviour):

# Python 2 only:
a = b / c            # with any types
# Python 2 and 3:
from past.utils import old_div

a = old_div(b, c)    # always same as / on Py2

长整数

短整数在 Python 3 中已经去除了,并且 long 已经变成了 int(没有 Lrepr 后面)

# Python 2 only
k = 9223372036854775808L

# Python 2 and 3:
k = 9223372036854775808
# Python 2 only
bigint = 1L

# Python 2 and 3
from future.builtins import int
bigint = int(1)

为了测试一个值是否是整数(任何类型):

# Python 2 only:
if isinstance(x, (int, long)):
    ...

# Python 3 only:
if isinstance(x, int):
    ...

# Python 2 and 3: option 1
from future.builtins import int    # subclass of long on Py2

if isinstance(x, int):             # matches both int and long on Py2
    ...

# Python 2 and 3: option 2
from past.builtins import
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值