为什么删除名为__builtins__的全局变量只能阻止REPL访问内置函数? [英] Why does deleting a global variable named __builtins__ prevent only the REPL from accessing builtins?

查看:82
本文介绍了为什么删除名为__builtins__的全局变量只能阻止REPL访问内置函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含以下内容的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆