__future__ 进口如何在幕后工作

Posted

技术标签:

【中文标题】__future__ 进口如何在幕后工作【英文标题】:How __future__ imports work under the hood 【发布时间】:2018-01-29 18:56:10 【问题描述】:

__future__ 模块让我很着迷——尤其是它能够改变在 python 中解析语句的方式。

最有趣的是如何做类似的事情

from __future__ import print_function

使您能够使用print(而不是print_function,就像您期望的任何其他正常导入一样)。

我已经彻底阅读了What is __future__ in Python used for and how/when to use it, and how it works,特别是遇到了一行:

Future 语句是对编译器的一个指令,即特定的 模块应该使用将被编译的语法或语义 在指定的 Python 未来版本中可用。

我很想知道究竟是什么让这成为可能。特别是像

from __future__ import division

可以在python2上启用真正的除法,而

from __future__ import barry_as_FLUFL

可以在 python3 上启用<> 语法(我觉得最有趣的是你必须从“__future__”导入一个特性才能向后兼容)。

总之,我想知道当__future__ 或其人工制品被导入时,编译器是如何理解和执行指令的。

【问题讨论】:

因为它不是正常导入。见docs.python.org/2/reference/simple_stmts.html#future @jonrsharpe "总之,我想知道当 future 或其人工制品被导入时,编译器是如何理解和执行指令的。“我已经完成了我的研究,但无论如何感谢您的反对。 我可能应该更改标题以阻止注意力持续时间短的人投反对票。 无论我的意见是否值得,我觉得这个问题肯定有一些 @Ev.Kounis 这 3 名反对者和 1 名密切投票者会不同意,但无论如何,就像我说的那样......可能是我最初的糟糕标题的错。 【参考方案1】:

from __future__ import print_function 告诉解析器not treat print as a keyword(将其保留为名称)。这样编译器会将其视为函数而不是语句。

为了跟踪这一点,compiler 结构有一个 c_future 字段,其中包含一个 PyFutureFeatures 对象,该对象跟踪哪些未来指令已启用。解析器和编译器的各个部分检查标志并改变行为。

这主要在future.c source file 中处理,它有一个future_parse() function,用于检查模块参数设置为__future__import from AST 对象,并根据找到的内容设置标志。

例如,对于barry_as_FLUFL'特征',解析器refuses != as syntax but accepts <> instead:

if (type == NOTEQUAL) 
    if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
                    strcmp(str, "!=")) 
        PyObject_FREE(str);
        err_ret->error = E_SYNTAX;
        break;
    
    else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
                    strcmp(str, "<>")) 
        PyObject_FREE(str);
        err_ret->text = "with Barry as BDFL, use '<>' "
                        "instead of '!='";
        err_ret->error = E_SYNTAX;
        break;
    

您可以通过查找FUTURE_* 标志listed in compile.h 来找到其他示例。

注意有__future__ Python module,但不直接参与代码的解析和编译;它只是为了让 Python 代码轻松访问有关指令的元数据(包括传递给 compile() function 的 flags 参数的位域值),仅此而已。

【讨论】:

我已经知道了。我想知道它是如何在幕后工作的……这就是这个问题的目的。 @cᴏʟᴅsᴘᴇᴇᴅ:这......相当广泛,但我会看看我能填写什么。 我觉得 barry 最有趣的是他必须来自__future__,而不是像__past__ 这样更明智的人。感谢您一如既往的出色回答。

以上是关于__future__ 进口如何在幕后工作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用:从 __future__ 使用 django 导入部门

如何使用 __future__ 注释从 self.__annotations__ 获取可调用的类对象?

如何训练inception网络

一旦 Futures 开始,你如何杀死它们?

为啥没有“外国进口 prim 不安全”?

如何让 numpy 数组的 FFT 工作?