未来¶
未来语句(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)
打印函数¶
将**打印语句**替换为**打印函数**是 Python 历史上最臭名昭著的决定之一。但是,此更改带来了一些灵活性,可以扩展 print
的功能。更多信息可以在 PEP 3105 中找到。
>>> print "Hello World" # print is a statement
Hello World
>>> from __future__ import print_function
>>> print "Hello World"
File "<stdin>", line 1
print "Hello World"
^
SyntaxError: invalid syntax
>>> print("Hello World") # print become a function
Hello World
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