gpt4 book ai didi

python - 为什么删除名为 __builtins__ 的全局变量只会阻止 REPL 访问内置函数?

转载 作者:行者123 更新时间:2023-11-28 22:16:22 25 4
gpt4 key购买 nike

我有一个包含以下内容的 python 脚本:

# foo.py

__builtins__ = 3
del __builtins__

print(int) # <- this still works

奇怪的是,使用 -i 标志执行此脚本 REPL 无法访问内置函数:

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 却不能?

最佳答案

CPython 不会在每次需要进行内置变量查找时查找 __builtins__。每个框架对象都有一个 f_builtins持有其内置变量 dict 的成员,内置变量查找从那里进行。

f_builtins 在框架对象创建时设置。如果新框架没有父框架 (f_back),或者与其父框架有不同的全局变量字典,则框架对象初始化查找__builtins__ 设置 f_builtins。 (如果新框架与其父框架共享全局字典,则它继承其父框架的 f_builtins。)这是 __builtins__ 参与内置变量查找的唯一方式.您可以在 _PyFrame_New_NoTrack 中查看处理此问题的代码.

当您在脚本中删除 __builtins__ 时,不会影响 f_builtins。在脚本的堆栈框架中执行的其余代码仍然可以看到内置函数。一旦脚本完成并且 -i 使您进入交互模式,每个交互命令都会获得一个新的堆栈帧(没有父级),并且 __builtins__ 查找将重复进行。这是删除的 __builtins__ 最终重要的时候。

关于python - 为什么删除名为 __builtins__ 的全局变量只会阻止 REPL 访问内置函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52221983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com