Python中的__future__是什么,以及如何/何时使用它以及如何工作


692

__future__经常出现在Python模块中。__future__即使阅读了python的__future__文档,我也不明白它的用途以及使用时间/方式。

有人可以举例说明吗?

关于__future__我收到的基本用法的一些答案似乎是正确的。

但是,我需要了解有关__future__工作原理的另一件事:

对我来说,最令人困惑的概念是当前的python版本如何包含未来版本的功能,以及如何使用当前版本的Python成功地编译使用未来版本的功能的程序。

我猜想当前版本包含了将来的潜在功能。但是,这些功能仅可通过使用获得,__future__因为它们不是当前标准。让我知道我是否正确。


10
这是将来声明的原始建议。我发现它有助于理解为什么它首先存在,因此何时以及如何使用它自然而然。 python.org/dev/peps/pep-0236
Jpaji Rajnish


3
将来的语句是对编译器的指令,即应使用将来指定的Python版本中可用的语法或语义来编译特定的模块。将来的声明旨在简化向Python的未来版本的移植,从而对语言进行不兼容的更改。它允许在该功能成为标准版本之前,按模块使用新功能。
shivam13juna

Answers:


383

通过__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 printprint在3.x中成为函数,失去其特殊属性作为关键字。反之亦然。

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>

151
别忘了from __future__ import braces:p
mdeous,2011年

13
@zoogleflatt如果您更喜欢制表符,则您不知道
PEP8

5
@glglgl从技术上讲,它只是说他们是首选。在阅读完为什么这样后,对我来说还不是很清楚,我猜想缩进级别必须完全匹配才能使代码更整洁?
Jpaji Rajnish

4
@zoogleflatt当然也与以下事实有关:大多数人使用4个空格进行1级缩进,出于兼容性原因,不建议使用一个制表符等效于8个空格,并且不鼓励将制表符和空格混合使用(重复,AFAIK,甚至不允许使用Py3)
glglgl 2015年

1
@whiteSkar我目前不是最新版本的python 3,但是我认为它仍在使用中,只是您可能不需要这些非常老的功能。在Python 3中,print绝对是一个函数,但是可能还有其他功能可以使用__future__。(编辑:请参阅docs.python.org/3/library/__future__.html仍在使用的地方。)
glglgl

195

当你做

from __future__ import whatever

您实际上不是在使用import语句,而是在将来的语句。您正在阅读错误的文档,因为您实际上并未在导入该模块。

以后的语句很特殊-它们更改了Python模块的解析方式,这就是为什么它们必须位于文件顶部的原因。它们为文件中的单词或符号赋予了新的(或不同的)含义。从文档:

将来的语句是对编译器的指令,即应使用将来指定的Python版本中可用的语法或语义来编译特定模块。将来的声明旨在简化向Python的未来版本的移植,从而对语言进行不兼容的更改。它允许在该功能成为标准版本之前,按模块使用新功能。

如果您确实要导入__future__模块,请执行

import __future__

然后照常访问它。


4
从技术上讲,它也是一个导入语句,因为相关名称绑定到局部变量。from __future__ import print_function都可以更改print关键字的行为,并具有等效的运行时效果print_function = __import__("__future__").print_function
pppery

112

__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)

1
因此,根据变量中的发行版本,如果您的解释器使用的是比所指示的版本更高的版本,那么这import __future__ xyz是无操作吗?

4
它有点类似于浏览器世界中的
polyfill

47

它可以用于使用某些功能,这些功能将在具有较旧版本的Python的同时以较新的版本显示。

例如

>>> from __future__ import print_function

将允许您将其print用作功能:

>>> print('# of entries', len(dictionary), file=sys.stderr)

29

已经有一些不错的答案,但是都没有一个完整的清单 __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 MESSAGEstyle语句。

unicode_literals

介绍bytes对象的文字语法。意味着诸如之类的陈述bytes('Hello world', 'ascii')可以简单地表达为b'Hello world'

generator_stop

StopIteration生成器函数内部使用的异常的使用替换为RuntimeError异常。

上面没有提到的另一种用法是该__future__语句还需要使用Python 2.1+解释器,因为使用较旧的版本将引发运行时异常。


参考文献


假设您处于离线状态,python如何知道将来的版本是否可用?如果您尚未在计算机上安装python的未来版本,它将如何使用未来的功能?
Mohsen Haddadi

25

还是说“既然是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


2

我发现非常有用的用途之一是print_functionfrom__future__模块。

在Python 2.7中,我希望将来自不同打印语句的字符打印在同一行上而没有空格。

可以在最后使用逗号(“,”)来完成此操作,但是它还会附加一个额外的空间。上面的语句用作:

from __future__ import print_function
...
print (v_num,end="")
...

这将v_num在一行中没有空格的情况下打印每次迭代的值。


-3

从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循环时,它将在下一行上打印*。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.