__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),仅此而已
我一直对 __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),仅此而已