我对__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,特别是遇到了一个特定的行:
未来的声明是指向编译器的特定指令 应该使用将要使用的语法或语义来编译模块 在指定的Python未来版本中提供。
我很想知道究竟是什么让这成为可能的复杂性。尤其是
之类的东西from __future__ import division
可以在python2上启用真正的除法,而
from __future__ import barry_as_FLUFL
可以在python3上启用<>
语法(我觉得最有趣的是你必须从&#34; __future__
&#34;中导入一个功能以实现向后兼容性。)
无论如何,总而言之,我想知道在导入__future__
或其人工制品时编译器如何理解和执行该指令。
答案 0 :(得分:7)
from __future__ import print_function
告诉解析器not treat print
as a keyword(将其保留为名称)。这样编译器将其视为函数而不是语句。
为了跟踪这一点,compiler
结构有一个c_future
字段,其中包含一个PyFutureFeatures
对象,用于跟踪已启用的指令。解析器和编译器的各个部分检查标志并改变行为。
这主要在future.c
source file处理,future_parse()
function有refuses !=
as syntax but accepts <>
instead检查import from
AST对象,模块参数设置为__future__
,并设置标记基于找到了什么。
例如,对于barry_as_FLUFL
'功能',解析器listed in compile.h
:
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_*
标记__future__
Python module找到其他示例。
请注意,有一个compile()
function,但它并没有直接参与代码的解析和编译;它只是让Python代码轻松访问有关指令的元数据(包括传递给{{3}}的flags
参数的位域值),仅此而已。