4

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

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

from __future__ import print_function

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

我已经阅读了 Python 中的 __future__ 是什么以及如何/何时使用它,以及它是如何彻底工作的,特别是遇到了一个特定的行:

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

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

from __future__ import division

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

from __future__ import barry_as_FLUFL

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

无论如何,总而言之,我想知道在__future__导入或导入其工件时编译器如何理解和执行该指令。

4

1 回答 1

7

from __future__ import print_function告诉解析器不要将其print视为关键字(而是将其保留为名称)。这样编译器将其视为函数而不是语句。

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

这主要在future.c源文件中处理,该文件具有一个future_parse()函数,用于检查import from模块参数设置为 的 AST 对象__future__,并根据找到的内容设置标志。

例如,对于barry_as_FLUFL“功能”,解析器拒绝作为语法,而是!=接受<>

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;
    }
}

您可以通过 grepping 中列出FUTURE_*的标志找到其他示例。compile.h

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

于 2017-08-21T16:08:59.660 回答