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

时间:2011-08-16 07:52:31

标签: python

包括我在内的人都知道Python中有一些名为__future__的内容,它出现在我阅读的很多模块中。像我这样沉闷的人甚至在阅读the Python's __future__ doc之后就不知道为什么会这样,以及如何/何时使用它。

所以用示例解释一下吗?

我已经快速得到了一些答案,从基本用法来看,这些答案看起来都是正确的。

但是,为了进一步了解__future__的工作原理:

我刚刚意识到一个关键因素让我感到困惑,当我试图理解它时,也就是说,当前的python版本如何包含将在未来版本中发布的内容? 如何在未来的python版本中使用新功能的程序如何通过当前的python版本成功编译?

所以,我现在想,当前版本已经打​​包了一些将在未来版本中包含的潜在功能 - 这是正确的吗?但这些功能仅由__future__提供,这是因为它尚未成为标准 - 我是对的吗?

10 个答案:

答案 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中的行为方式。

这有更多解释:http://python3porting.com/noconv.html

答案 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)的格式返回。 OptionalReleaseMandatoryRelease 都是 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循环时,它都会将*打印到下一行。