__future__ 导入是如何工作的

How __future__ imports work under the hood

我一直对 __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,特别是遇到了特定的行:

A future statement is a directive to the compiler that a particular module should be compiled using syntax or semantics that will be available in a specified future release of Python.

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

这样的东西
from __future__ import division

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

from __future__ import barry_as_FLUFL

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

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

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

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

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

例如,对于 barry_as_FLUFL 'feature',解析器 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, but it is not directly involved in the parsing and compilation of code; it is merely there to give Python code easy access to metadata about directives (including bitfield values to pass to the flags argument of the compile() function),仅此而已