包括我在内的人都知道Python中有一些名为__future__
的内容,它出现在我阅读的很多模块中。像我这样沉闷的人甚至在阅读the Python's __future__
doc之后就不知道为什么会这样,以及如何/何时使用它。
所以用示例解释一下吗?
我已经快速得到了一些答案,从基本用法来看,这些答案看起来都是正确的。
但是,为了进一步了解__future__
的工作原理:
我刚刚意识到一个关键因素让我感到困惑,当我试图理解它时,也就是说,当前的python版本如何包含将在未来版本中发布的内容? 如何在未来的python版本中使用新功能的程序如何通过当前的python版本成功编译?
所以,我现在想,当前版本已经打包了一些将在未来版本中包含的潜在功能 - 这是正确的吗?但这些功能仅由__future__
提供,这是因为它尚未成为标准 - 我是对的吗?
答案 0 :(得分:305)
如果包含__future__
模块,您可以慢慢习惯于不兼容的更改或引入新关键字的更改。
例如,对于使用上下文管理器,您必须在2.5中执行from __future__ import with_statement
,因为with
关键字是新的,不应再用作变量名。要在Python 2.5或更早版本中使用with
作为Python关键字,您需要使用上面的导入。
另一个例子是
from __future__ import division
print 8/7 # prints 1.1428571428571428
print 8//7 # prints 1
如果没有__future__
内容,则print
个语句都会打印1
。
内部差异在于,如果没有导入,/
会映射到__div__()
方法,而使用__truediv__()
时,会使用//
。 (无论如何,__floordiv__()
调用print
。)
Apropos print
:>>> print
>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
成为3.x中的一个函数,失去了作为关键字的特殊属性。所以它反过来了。
{{1}}
答案 1 :(得分:167)
当你这样做时
from __future__ import whatever
您实际上并未使用import
语句,而是future statement。您正在阅读错误的文档,因为您实际上并未导入该模块。
Future语句很特别 - 它们会改变Python模块的解析方式,这就是为什么必须位于文件顶部的原因。它们为文件中的单词或符号赋予新的或不同的含义。来自文档:
未来语句是指向编译器的指令,即应使用将在Python的指定未来版本中提供的语法或语义来编译特定模块。未来的声明旨在简化向未来版本的Python的迁移,从而引入对语言的不兼容更改。它允许在发布功能成为标准版本之前,逐个模块地使用新功能。
如果您确实要导入__future__
模块,请执行
import __future__
然后像往常一样访问它。
答案 2 :(得分:101)
__future__
是一个伪模块,程序员可以使用它来启用与当前解释器不兼容的新语言功能。例如,表达式11/4
当前的计算结果为2
。如果执行它的模块通过执行以下命令启用了真正的除法:
from __future__ import division
表达式11/4
将评估为2.75
。通过导入__future__
模块并评估其变量,您可以看到新功能何时首次添加到该语言以及何时成为默认语言:
>>> import __future__
>>> __future__.division
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
答案 3 :(得分:41)
它可用于使用较新版本中出现的功能,同时使用旧版本的Python。
例如
>>> from __future__ import print_function
允许您将print
用作函数:
>>> print('# of entries', len(dictionary), file=sys.stderr)
答案 4 :(得分:23)
或者就像说“因为这是python v2.7,使用不同的'print'函数,它已被添加到python v2.7,在python 3中添加之后。所以我的'print'将不会更长的语句(例如打印“消息”)但是函数(例如,print(“message”,options)。那样当我的代码在python 3中运行时,'print'不会中断。“
在
from __future__ import print_function
print_function是包含'print'新实现的模块,根据它在python v3中的行为方式。
答案 5 :(得分:18)
已经有一些很好的答案,但它们都没有提供__future__
语句当前支持的完整列表。
简单地说, __future__语句迫使Python解释器使用该语言的新功能。
目前支持的功能如下:
nested_scopes
:
在Python 2.1之前,以下代码会引发 NameError :
def f():
...
def g(value):
...
return g(value-1) + 1
...
from __future__ import nested_scopes
指令将允许启用此功能。
generators
:
引入了生成器函数,例如下面的函数,用于在连续函数调用之间保存状态:
def fib():
a, b = 0, 1
while 1:
yield b
a, b = b, a+b
division
:
经典分区用于Python 2.x版本。意味着某些除法语句返回合理的除法近似值(“真正的除法”),而其他除法句则返回最低限度(“地板除法”)。从Python 3.0开始,真正的除法由x/y
指定,而得分除以x//y
指定。
from __future__ import division
指令强制使用Python 3.0样式分区。
absolute_import
:
允许括号括起多个import
语句。例如:
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
LEFT, DISABLED, NORMAL, RIDGE, END)
而不是:
from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
LEFT, DISABLED, NORMAL, RIDGE, END
或者:
from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END
with_statement
:
在Python中添加语句“with”作为关键字,以消除对try/finally
语句的需要。这种情况的常见用途是在执行文件I / O时,例如:
with open('workfile', 'r') as f:
read_data = f.read()
print_function
:
强制使用Python 3括号样式print
函数调用而不是print MESSAGE
样式的print语句。
unicode_literals
:
介绍bytes
对象的文字语法。这意味着bytes('Hello world', 'ascii')
之类的陈述可以简单地表达为b'Hello world'
。
generator_stop
:
将生成器函数内使用的StopIteration
异常替换为RuntimeError
异常。
上面没有提到的另一个用途是__future__
语句也强制使用Python 2.1+解释器,因为使用旧版本会抛出运行时异常。
<强>参考文献:强>
答案 6 :(得分:3)
我发现其中一个非常有用的用途是来自print_function
模块的__future__
。
在Python 2.7中,我希望来自不同打印语句的字符在没有空格的同一行上打印。
最后可以使用逗号(&#34;,&#34;)来完成,但它还会附加一个额外的空格。 以上陈述用作:
from __future__ import print_function
...
print (v_num,end="")
...
这将在每行迭代中打印v_num
的值,而不是空格。
答案 7 :(得分:0)
显式优于隐式
from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
[信用:@mdeous]
答案 8 :(得分:0)
__future__
是一个蟒蛇 module。添加它是为了避免混淆分析导入语句并期望找到它们正在导入的模块的现有工具。它是在 2.1 版中添加的,因此如果在 2.1 版之前使用,导入 __future__
将失败。
现在看这个代码:
>>> from __future__ import division
>>> division
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 131072)
部门以_Feature(OptionalRelease, MandatoryRelease, CompilerFlag)
的格式返回。 OptionalRelease 和 MandatoryRelease 都是 5 元组,形式为:
(
PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
PY_MINOR_VERSION, # the 1; an int
PY_MICRO_VERSION, # the 0; an int
PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string
PY_RELEASE_SERIAL # the 3; an int
)
所以在我们的例子中,OptionalRelease 是 2.2.0a2,MandatoryRelease 是 3.0.0a0。
OptionalRelease 告诉我们该功能被接受时的第一个版本。
MandatoryRelease 预测特征何时成为语言的一部分或显示特征何时成为语言的一部分;在此后或之后的版本中,模块不再需要 future 语句来使用相关功能,但可以继续使用此类导入。如果 MandatoryRelease 为 None,则该计划的功能将被删除。
CompilerFlag 是(位域)标志,应在第四个参数中传递给内置函数 compile() 以在动态编译代码中启用该功能。此标志存储在 _Feature 实例的 compiler_flag 属性中。
答案 9 :(得分:-2)
在Python 3.0之后,print不再只是一个声明,而是一个函数。并包含在PEP 3105中。
另外我认为Python 3.0包仍然具有这些特殊功能。让我们通过传统的金字塔计划来看它的可用性&#34;在Python中:
from __future__ import print_function
class Star(object):
def __init__(self,count):
self.count = count
def start(self):
for i in range(1,self.count):
for j in range (i):
print('*', end='') # PEP 3105: print As a Function
print()
a = Star(5)
a.start()
Output:
*
**
***
****
如果我们使用普通打印功能,我们将无法获得相同的输出,因为print()带有额外的换行符。所以每次执行内部for循环时,它都会将*打印到下一行。