未来

未来语句(Future statements)告诉解释器以未来 Python 版本的语义来编译某些语法。换句话说,Python 使用 from __future__ import feature 将其他更高版本 Python 的特性移植到当前解释器。在 Python 3 中,许多特性,例如 print_function,已经启用,但我们仍然保留这些未来语句以实现向后兼容性。

未来语句**不是**导入语句。未来语句会改变 Python 解释代码的方式。它们**必须**位于文件的顶部。否则,Python 解释器将引发 SyntaxError

如果您对未来语句感兴趣并希望获得更多解释,可以在 PEP 236 - Back to the __future__ 找到更多信息。

列出所有新特性

__future__ 是一个 Python 模块。我们可以用它来检查可以导入到当前 Python 解释器的未来特性有哪些。有趣的是 import __future__ **不是**未来语句,它是一个导入语句。

>>> from pprint import pprint
>>> import __future__
>>> pprint(__future__.all_feature_names)
['nested_scopes',
 'generators',
 'division',
 'absolute_import',
 'with_statement',
 'print_function',
 'unicode_literals',
 'barry_as_FLUFL',
 'generator_stop',
 'annotations']

未来语句不仅改变了 Python 解释器的行为,还将 __future__._Feature 导入到当前程序中。

>>> from __future__ import print_function
>>> print_function
_Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 65536)

Unicode

与**打印函数**一样,将文本转换为 Unicode 也是另一个臭名昭著的决定。然而,许多现代编程语言的文本都是 Unicode。此更改迫使我们在早期对文本进行解码,以防止在程序运行一段时间后出现运行时错误。更多信息可以在 PEP 3112 中找到。

>>> type("Guido") # string type is str in python2
<type 'str'>
>>> from __future__ import unicode_literals
>>> type("Guido") # string type become unicode
<type 'unicode'>

除法

有时,当除法结果为 int 或 long 时,会让人感到反直觉。在这种情况下,Python 3 默认启用**真除法**。但是,在 Python 2 中,我们必须将 division 移植到当前解释器。更多信息可以在 PEP 238 中找到。

>>> 1 / 2
0
>>> from __future__ import division
>>> 1 / 2   # return a float (classic division)
0.5
>>> 1 // 2  # return a int (floor division)
0

注解

在 Python 3.7 之前,如果当前作用域中不存在注解,则无法在类或函数中赋值注解。一种常见的情况是容器类的定义。

class Tree(object):

    def insert(self, tree: Tree): ...

示例

$ python3 foo.py
Traceback (most recent call last):
  File "foo.py", line 1, in <module>
    class Tree(object):
  File "foo.py", line 3, in Tree
    def insert(self, tree: Tree): ...
NameError: name 'Tree' is not defined

在这种情况下,类的定义尚不可用。Python 解释器无法在定义时解析注解。为了解决这个问题,Python 使用字符串字面量来替换类。

class Tree(object):

    def insert(self, tree: 'Tree'): ...

3.7 版之后,Python 引入了未来语句 annotations 来执行延迟求值。它将在 Python 4 中成为默认特性。有关更多信息,请参阅 PEP 563

from __future__ import annotations

class Tree(object):

    def insert(self, tree: Tree): ...

BDFL 退休

Python 3.1 中新增

PEP 401 只是一个彩蛋。此特性将当前解释器带回过去。它在 Python 3 中启用了菱形运算符 <>

>>> 1 != 2
True
>>> from __future__ import barry_as_FLUFL
>>> 1 != 2
  File "<stdin>", line 1
    1 != 2
       ^
SyntaxError: with Barry as BDFL, use '<>' instead of '!='
>>> 1 <> 2
True

花括号

braces 是一个彩蛋。源代码可以在 future.c 中找到。

>>> from __future__ import braces
  File "<stdin>", line 1
SyntaxError: not a chance