为什么删除名为__builtins__的全局变量只能阻止REPL访问内置函数? [英] Why does deleting a global variable named __builtins__ prevent only the REPL from accessing builtins?
问题描述
我有一个包含以下内容的python脚本:
I have a python script with the following contents:
# foo.py
__builtins__ = 3
del __builtins__
print(int) # <- this still works
奇怪的是,使用 -i
标志执行此脚本可以防止 only REPL访问内置文件:
Curiously, executing this script with the -i
flag prevents only the REPL from accessing builtins:
aran-fey@starlight ~> python3 -i foo.py
<class 'int'>
>>> print(int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'print' is not defined
该脚本如何访问内置函数,但是REPL不能?
How come the script can access builtins, but the REPL can't?
推荐答案
CPython不会查找 __ builtins __
每次需要执行内置变量查找。每个框架对象都有一个 f_builtins
成员保留其内置变量dict,并通过内置变量查找。
CPython doesn't look up __builtins__
every time it needs to do a built-in variable lookup. Each frame object has an f_builtins
member holding its built-in variable dict, and built-in variable lookup goes through there.
f_builtins
在创建框架对象时设置。如果新框架没有父框架 ( f_back
),或者父框架有不同的全局变量dict ,然后框架对象初始化将查找 __ builtins __
来设置 f_builtins
。 (如果新框架与其父框架共享全局字典,则它将继承其父框架的 f_builtins
。)这是 __ builtins __
涉及内置变量查找。您可以在 _PyFrame_New_NoTrack
。
f_builtins
is set on frame object creation. If a new frame has no parent frame (f_back
), or a different global variable dict from its parent frame, then frame object initialization looks up __builtins__
to set f_builtins
. (If the new frame shares a global dict with its parent frame, then it inherits its parent's f_builtins
.) This is the only way __builtins__
is involved in built-in variable lookup. You can see the code that handles this in _PyFrame_New_NoTrack
.
当您删除a中的 __ builtins __
时脚本,不会影响 f_builtins
。在脚本的堆栈框架中执行的其余代码仍然具有内置功能。一旦脚本完成并且 -i
使您进入交互模式,每个交互命令都会获得一个新的堆栈帧(没有父级),以及 __ builtins __
查找重复进行。这是删除的 __ builtins __
最终重要的时候。
When you delete __builtins__
inside a script, that doesn't affect f_builtins
. The rest of the code executing in the script's stack frame still sees builtins. Once the script completes and -i
drops you into interactive mode, every interactive command gets a new stack frame (with no parent), and the __builtins__
lookup is repeated. This is when the deleted __builtins__
finally matter.
这篇关于为什么删除名为__builtins__的全局变量只能阻止REPL访问内置函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!