问题:Python中的__future__是什么,以及如何/何时使用它以及如何工作
__future__
经常出现在Python模块中。__future__
即使阅读了python的__future__
文档,我也不明白它的用途以及使用时间/方式。
有人可以举例说明吗?
关于__future__
我收到的基本用法的一些答案似乎是正确的。
但是,我需要了解有关__future__
工作原理的另一件事:
对我来说,最令人困惑的概念是当前的python版本如何包含未来版本的功能,以及如何使用当前版本的Python成功地编译使用未来版本的功能的程序。
我猜想当前版本包含了将来的潜在功能。但是,这些功能仅可通过使用获得,__future__
因为它们不是当前标准。让我知道我是否正确。
回答 0
通过__future__
包含模块,您可以慢慢习惯不兼容的更改或引入新关键字的更改。
例如,对于使用上下文管理器,您必须from __future__ import with_statement
在2.5中进行操作,因为with
关键字是new,不再应该用作变量名。为了with
在Python 2.5或更早版本中用作Python关键字,您将需要使用上面的import。
另一个例子是
from __future__ import division
print 8/7 # prints 1.1428571428571428
print 8//7 # prints 1
没有这些__future__
东西,两个print
语句都将打印出来1
。
内部差异在于没有导入时,/
映射到__div__()
方法,而使用导入__truediv__()
。(无论如何,请//
调用__floordiv__()
。)
Apropos print
:print
在3.x中成为函数,失去其特殊属性作为关键字。反之亦然。
>>> print
>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
回答 1
当你做
from __future__ import whatever
您实际上不是在使用import
语句,而是在将来的语句。您正在阅读错误的文档,因为您实际上并未在导入该模块。
以后的语句很特殊-它们更改了Python模块的解析方式,这就是为什么它们必须位于文件顶部的原因。它们为文件中的单词或符号赋予了新的(或不同的)含义。从文档:
将来的语句是对编译器的指令,即应使用将来指定的Python版本中可用的语法或语义来编译特定模块。将来的声明旨在简化向Python的未来版本的移植,从而对语言进行不兼容的更改。它允许在该功能成为标准版本之前,按模块使用新功能。
如果您确实要导入__future__
模块,请执行
import __future__
然后照常访问它。
回答 2
__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
它可以用于使用某些功能,这些功能将在具有较旧版本的Python的同时以较新的版本显示。
例如
>>> from __future__ import print_function
将允许您将其print
用作功能:
>>> print('# of entries', len(dictionary), file=sys.stderr)
回答 4
已经有一些不错的答案,但是都没有一个完整的清单 __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
with
在Python中将该语句作为关键字添加,以消除对try/finally
语句的需要。在执行文件I / O时,通常的用法是:
with open('workfile', 'r') as f:
read_data = f.read()
print_function
:
强制使用Python 3括号样式print()
函数调用代替print MESSAGE
style语句。
unicode_literals
介绍bytes
对象的文字语法。意味着诸如之类的陈述bytes('Hello world', 'ascii')
可以简单地表达为b'Hello world'
。
generator_stop
将StopIteration
生成器函数内部使用的异常的使用替换为RuntimeError
异常。
上面没有提到的另一种用法是该__future__
语句还需要使用Python 2.1+解释器,因为使用较旧的版本将引发运行时异常。
参考文献
- https://docs.python.org/2/library/ 将来的 .html
- https://docs.python.org/3/library/ 将来的 .html
- https://docs.python.org/2.2/whatsnew/node9.html
- https://www.python.org/dev/peps/pep-0255/
- https://www.python.org/dev/peps/pep-0238/
- https://www.python.org/dev/peps/pep-0328/
- https://www.python.org/dev/peps/pep-3112/
- https://www.python.org/dev/peps/pep-0479/
回答 5
还是说“既然是python v2.7,请在python 3中添加它后,再使用另一个已添加到python v2.7中的’print’函数,因此我的’print’将不再是语句(例如,打印“ message”),但具有功能(例如,print(“ message”,选项)。这样,当我的代码在python 3中运行时,“ print”不会中断。”
在
from __future__ import print_function
print_function是包含“ print”的新实现的模块,具体取决于python v3中的行为。
这有更多解释:http : //python3porting.com/noconv.html
回答 6
我发现非常有用的用途之一是print_function
from__future__
模块。
在Python 2.7中,我希望将来自不同打印语句的字符打印在同一行上而没有空格。
可以在最后使用逗号(“,”)来完成此操作,但是它还会附加一个额外的空间。上面的语句用作:
from __future__ import print_function
...
print (v_num,end="")
...
这将v_num
在一行中没有空格的情况下打印每次迭代的值。
回答 7
从Python 3.0开始,print不再只是一个语句,而是一个函数。并包含在PEP 3105中。
我也认为Python 3.0包仍然具有这些特殊功能。让我们通过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循环时,它将在下一行上打印*。