sys._getframe()。f_builtins和__builtins __.__ dict__等效吗?

时间:2017-07-03 05:47:35

标签: python python-3.x

如果我是对的:

  • sys._getframe().f_builtins是当前调用堆栈顶部框架中的内置对象;以及

  • __builtins__.__dict__是当前模块中的内置对象。

sys._getframe().f_builtins__builtins__.__dict__的值有何不同?它们总是具有相同的值,即相同的内置对象吗?

2 个答案:

答案 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代码可以做的事情。