__future__进口如何在引擎盖下工作 [英] How __future__ imports work under the hood
问题描述
__future__
模块让我着迷-尤其是它更改python语句解析方式的能力.
I've been fascinated by the __future__
module - in particular, its ability to change the way statements are parsed in python.
最有趣的是如何做
from __future__ import print_function
使您能够使用print
(而不是print_function
,就像您期望其他任何正常导入一样).
Enables you to use print
(and not print_function
, like you would expect any other normal import to do).
I have read What is __future__ in Python used for and how/when to use it, and how it works thoroughly and in particular came across a particular line:
future语句是对编译器的指令,即特定的 模块应使用以下语法或语义进行编译: 在指定的将来的Python版本中可用.
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.
我很想知道究竟是什么使它成为可能的复杂性.特别是
I would love to know the intricacies of what exactly makes this possible. In particular, how something like
from __future__ import division
可以在python2上启用真正的除法,而
Can enable true division on python2, while
from __future__ import barry_as_FLUFL
可以在python3上启用<>
语法(我觉得最有趣的是,为了向后兼容,您必须从"__future__
"导入功能).
Can enable the <>
syntax on python3 (what I find most funny is that you have to import a feature from "__future__
" for backward compatibility).
总而言之,我想知道在导入__future__
或其伪像时编译器如何理解和执行该指令.
Anyway, to summarise, I would like to know how the directive is understood and executed by the compiler when __future__
or its artefacts are imported.
推荐答案
from __future__ import print_function
告诉解析器
from __future__ import print_function
tells the parser to not treat print
as a keyword (leaving it as a name instead). That way the compiler treats it as the function and not a statement.
要对此进行跟踪,compiler
结构具有一个c_future
字段,该字段包含一个PyFutureFeatures
对象,该对象跟踪已启用了哪些将来的指令.解析器和编译器的各个部分检查标志并更改行为.
To track this, the compiler
struct has a c_future
field that holds a PyFutureFeatures
object that tracks which future directives have been enabled. Various parts of the parser and compiler check the flags and alter behaviour.
这主要在 future.c
源文件中进行处理,其中具有 future_parse()
函数检查模块参数设置为__future__
的import from
AST对象,并根据找到的内容设置标志.
This is mostly handled in the future.c
source file, which has a future_parse()
function that checks for import from
AST objects with the module parameter set to __future__
, and sets flags based on what is found.
例如,对于barry_as_FLUFL
功能",解析器拒绝!=
作为语法,但接受<>
:
For example, for the barry_as_FLUFL
'feature', the parser 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;
}
}
您可以通过grepping FUTURE_*
标志列在compile.h
中.
You can find the other examples by grepping for the FUTURE_*
flags listed in compile.h
.
请注意,有一个 __future__
Python模块,但是它是不直接参与代码的解析和编译;仅仅是为了使Python代码可以轻松访问有关指令的元数据(包括要传递给compile()
函数),仅此而已.
Note that there is a __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), nothing more.
这篇关于__future__进口如何在引擎盖下工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!