Python 2 / 3 兼容性,类似 6,但有利于 Python 3
项目描述
让我们现在编写 Python 3!
当最好的 Python 2/Python 3 兼容性模块——尤其是 Benjamin Peterson 发明的著名的 *six* 库 ——被创建时,它们是从 Python 2 程序员开始了解 Python 3 的角度编写的。如果你使用6 个,您的代码是兼容的,但停留在 Python 2 习惯用法中。
九转六颠倒。您尽可能多地使用 Python 3 惯用语编写代码,并且修补的是 Python 2“版本”。不用说,这种方法更具前瞻性。
当你编写 Python 时,你应该编写 Python 3,并确保在 Python 2.7 上运行一段时间。
九促进了这一观点。您可以编写尽可能 3ish 的代码,同时仍支持 2.6。
例如,您不再键入unicode,而是键入str,并且在 Python 2 上,九 使str指向unicode(如果您使用我们的样板)。此外,在 Python 2 上, map、zip和filter具有 Python 3 的行为,这意味着它们返回迭代器,而不是列表。
老实说,您不应该再花时间在 Python 2.6 上, 自 2013 年 10 月发布最终版本 (2.6.9) 以来,它不再受支持。也没有人使用 3.0 或 3.1。
Python 2.7 终于在 2020 年的第一天走向灭亡。
九非常稳定,不太可能改变,因为它解决了一个永远不会改变的老问题。如果9个月甚至几年没有更新,没有人应该感到惊讶。
九人的作者将此模块捐赠给公共领域。
要了解在单个代码库中实现 2&3 兼容性所涉及的大部分复杂性,我建议阅读以下内容:http: //lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/
使用九
在每个模块中,首先声明一个文本编码并从 __future__ 导入 Python 3 行为。然后根据这个样板文件从九导入变量:
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function,
unicode_literals)
from nine import (IS_PYTHON2, str, basestring, native_str, chr, long,
integer_types, class_types, range, range_list, reraise,
iterkeys, itervalues, iteritems, map, zip, filter, input,
implements_iterator, implements_to_string, implements_repr, nine,
nimport)
我知道那很丑。你期待什么?九是 3 的平方。好的,在许多情况下,您可以少花钱:
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function,
unicode_literals)
from nine import IS_PYTHON2, nimport, nine, range, str, basestring
但是在第二种情况下,你需要记住在使用时导入丢失的东西,期望你会记住是不现实的,是吗?
统一码
由于unicode_literals导入,模块中的所有字符串文字都成为 unicode objects。无需为每个字符串文字添加“u”前缀。这是更明智的方法,因为在 Python 3 中,字符串默认是 unicode 对象,然后您可以指示b"this is a byte string literal"。实际上需要是字节字符串的文字是非常罕见的。但是你不会相信有多少开发人员无理地害怕采取这个简单的步骤......
如果您对 Unicode 不太了解,请阅读 每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求(没有借口!)
导入移动的东西
许多标准库模块在 Python 3 中被重命名,但有九个可以提供帮助。nimport函数获取新的 Python 3 名称,但如果在 Python 2 中运行,则知道要导入旧名称。例如,不要编写此代码来导入 pickle:
# Bad:
try:
import cPickle as pickle # Python 2.x
except ImportError:
import pickle # Python 3 automatically uses the C version.
…你可以这样写:
# Good:
pickle = nimport('pickle')
对于已移动的变量:在参数中,请用冒号分隔模块和变量:
name2codepoint = nimport('html.entities:name2codepoint')
想要StringIO?我建议您改为建立列表。但如果你真的需要它:
# Good:
if IS_PYTHON2:
from cStringIO import StringIO as BytesIO, StringIO
NativeStringIO = BytesIO
else:
from io import BytesIO, StringIO
NativeStringIO = StringIO
我们对 Python 版本差异的报道可能并不详尽,但欢迎贡献。
如有疑问, 请使用来源!
请参阅 GitHub 上的项目页面!我们还在 Travis-CI 进行持续集成。
九班装饰师
我们为魔术方法的 Python 2 和 3 兼容性提供了一个类装饰器。魔术方法是以两条下划线开头和结尾的方法。
您使用它们的 Python 3 名称定义魔术方法,并且在 Python 2 上,它们获得相应的名称。你可以写:
__next__()。使用next(iterator)函数进行迭代。
__str__():必须返回一个 unicode 字符串。在 Python 2 中,我们 根据您的__str__( ) 为您实现__unicode__()和__bytes__ () 。
__repr__():必须返回一个 unicode 字符串。
__bytes__():必须返回一个字节对象。
例子:
@nine
class MyClass(object):
def __str__(self):
return "MyClass" # a unicode string
移植步骤
当您开始在 Python 2 代码上应用9以实现 Python 3 兼容性时,您可以从以下任务列表开始。这并不详尽,只是一个好的开始。您可以一次升级一个.py模块:
如上所述添加我们的标题。
用 print 函数替换出现的 print 语句(这大致意味着,添加括号)。
替换str(),通常用九的native_str()或bytes()。
用str()和from 9 import str替换unicode()
用__str__()方法替换__unicode__( )方法;在类上应用@nine装饰器。
还要在定义__repr__()的类上应用@nine装饰器。
搜索范围并替换为九的范围或range_list
一些 dict 方法在 Python 3 中返回不同的东西。只有当您需要在两个版本中完全相同的行为时,才替换:
d.keys()或d.iterkeys()与九个iterkeys(d);
d.values()或d.itervalues()与九的itervalues(d) ; 和
d.items()或d.iteritems()与九个iteritems(d)。
请注意,在九个版本中,map()、zip()和filter()始终返回独立于 Python 版本的迭代器。
如果您之前使用过六个或其他兼容性库:
用九的基本字符串替换string_types
然后在您希望支持的所有 Python 版本中运行您的测试。
如果我忘了提什么,你 能提出一个拉取请求吗,为了其他开发人员的利益?
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。
源分布
内置分布
9-1.1.0.tar.gz的哈希值
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | e8a96b6326341637d25ca9c257c1d2af4033c957946438d9d37bf6eb798d3bbe |
|
| MD5 | b7430863fbd8569cd43e323b01657a94 |
|
| 布莱克2-256 | ba1f0c7e2a1e28497df5d207199b5e70aa998e501659eeb84076a6cf78809540 |