【问题标题】:How __future__ imports work under the hood__future__ 进口如何在幕后工作
【发布时间】: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 名密切投票者会不同意,但无论如何,就像我说的那样......可能是我最初的糟糕标题的错。

标签: python python-2.7 import python-internals compiler-directives


【解决方案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() functionflags 参数的位域值),仅此而已。

【讨论】:

  • 我已经知道了。我想知道它是如何在幕后工作的……这就是这个问题的目的。
  • @cᴏʟᴅsᴘᴇᴇᴅ:这......相当广泛,但我会看看我能填写什么。
  • 我觉得 barry 最有趣的是他必须来自__future__,而不是像__past__ 这样更明智的人。感谢您一如既往的出色回答。
猜你喜欢
  • 2014-11-18
  • 2011-02-17
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多