我们现在都知道(我希望如此),Python 3 正在慢慢开始取代 Python 2.x。当然,大多数现有代码最终移植还需要很多年,但我们现在可以在 2.x 版本代码中做一些事情,让切换更容易。
显然,了解3.x 中的新功能会有所帮助,但是我们现在可以做些什么来让即将到来的转换更加轻松(以及在需要时更容易将更新输出到并发版本)?我特别考虑了我们可以用哪些行来开始我们的脚本,这将使早期版本的 Python 更类似于 3.x,尽管其他习惯也是受欢迎的。
我能想到的添加到脚本顶部的最明显的代码是:
from __future__ import division from __future__ import print_function try: range = xrange except NameError: pass
我能想到的最明显的习惯是 "{0} {1}!".format("Hello", "World") 字符串格式化。
"{0} {1}!".format("Hello", "World")
还有其他什么好习惯可以养成吗?
很棒的想法!为兼容 Python 3 而准备 Python 2.x 代码有助于简化最终的迁移,还有其他几种方法可以使这种过渡更加顺利。除了您的建议外,这里还有一些其他更改和最佳实践:
除了division和 之外print_function,还请考虑以下其他__future__导入:
division
print_function
__future__
from __future__ import unicode_literals # Makes string literals Unicode by default from __future__ import absolute_import # Enforces explicit relative imports
six
future
six和库future提供了用于编写在 Python 2 和 3 上均可运行的代码的实用程序。例如,six提供six.moves处理更改位置的导入的功能:
six.moves
from six.moves import range # Replaces xrange with range in both versions from six.moves import input # Maps raw_input to input in Python 2, or uses input in Python 3
str.format()
"{greeting}, {name}!".format(greeting="Hello", name="World")
items()
iteritems()
for key, value in my_dict.items(): # Do something
使用items()overiteritems()可确保兼容性,但要注意大型词典的内存。在这里six也有six.iteritems帮助。
six.iteritems
Python 3 对文本(Unicode)和二进制数据(字节)有区别地对待,因此最好做好准备:
# Explicitly encode/decode text for file or network operations text = "hello" binary_data = text.encode('utf-8') decoded_text = binary_data.decode('utf-8')
io.open
在 Python 2 中,io.open提供与 Python 3 兼容的文件处理和编码支持:
import io with io.open('file.txt', 'r', encoding='utf-8') as f: contents = f.read()
next()
为了准备 Python 3 的next()功能并避免混淆,请始终next()明确使用:
my_iter = iter([1, 2, 3]) first_item = next(my_iter)
__bool__
__nonzero__
在 Python 3 中,定义真实性的__bool__替换为:__nonzero__
class MyClass: def __bool__(self): return True __nonzero__ = __bool__ # For Python 2 compatibility
Python 3 用于as异常:
as
try: # Some operation except SomeException as e: print(e)
None
在 Python 3 中,None与非 None 值(例如None < 5)进行比较会引发错误,因此请使用is None或is not None:
None < 5
is None
is not None
if my_var is None: # Do something
__metaclass__
对于需要元类的类,请使用与 Python 2 和 3 兼容的语法:
class MyClass(object, metaclass=MyMetaClass): pass
或者,你可以__metaclass__在 Python 2 中的类顶部设置:
class MyClass: __metaclass__ = MyMetaClass
print
print()
//
__init__
super()
super(ClassName, self).__init__()
这些策略将使您的代码具有更好的 Python 3 兼容性,并有助于使最终的过渡变得更加容易。