如果我是对的:
sys._getframe().f_builtins
是当前调用堆栈顶部框架中的内置对象;以及
__builtins__.__dict__
是当前模块中的内置对象。
sys._getframe().f_builtins
和__builtins__.__dict__
的值有何不同?它们总是具有相同的值,即相同的内置对象吗?
答案 0 :(得分:2)
sys._getframe().f_builtins
和__builtins__.__dict__
的值有何不同?它们总是具有相同的值,即相同的内置对象吗?
是
Python中的内置名称在范围和名称空间中保持不变。这就是为什么他们被称为"内置" ;您可以从任何地方访问它们,因为它们已构建到解释器中。除非您明确更改了内置映射,否则它们将是相同的。
但不仅如此,他们都指向相同的内置映射。这意味着对__builtins__.__dict__
的更改将更改为sys._get_frame().f_builtins
,反之亦然。
这也可以通过一个简单的例子进行测试:
>>> import sys
>>> frame = sys._getframe()
>>>
>>> frame.f_builtins == __builtins__.__dict__
True
>>> frame.f_builtins['abc'] = 3
>>> frame.f_builtins['abc']
3
>>> frame.f_builtins == __builtins__.__dict__
True
>>>
当我们向frame.f_builtins
添加新的内置名称时,__builtins__.__dict__
也会更改。
注意: __builtins__
是一个CPython实现细节,可能在其他Python实现中不存在。所以不要依赖它。相反,请使用builtins
模块。
答案 1 :(得分:1)
我不知道任何执行框架内置(通过其f_builtins
属性评估)与仅访问__builtin__
模块不同的情况。但是,重要的是要注意f_builtins
如果您有一些自定义代码操作它可能会有所不同。
根据this source:
直接可访问的方法是使用eval()或exec并指定一个 '全局'带有 builtins 成员的字典。如果存在,这个 成为代码的内置函数,显示在框架中的f_builtins中, 等等。任何具有f_builtins非标准值的代码框都是 a'限制'框架,以及CPython内部的各种各样的行为 不同的(例如,通常他们禁止各种操作) 在类上设置属性)。反过来所有这一切似乎都是 目前支持现在已弃用的rexec.py模块,该模块尝试 (你猜对了)限制了一些不受信任的Python代码可以做的事情。