[英]Where does a compiled function get its globals()?
I've discovered that if I write something like:我发现如果我写这样的话:
code = f"lambda a, b: add(a, b)"
my_globals = globals().copy()
my_globals['add'] = operator.__add__
result = eval(code, my_globals, {})
Then result(3, 5)
has the value 8, just like I want.然后
result(3, 5)
的值为 8,就像我想要的那样。
When I look at the disassembly of result
, I see:当我查看
result
的反汇编时,我看到:
0 LOAD_GLOBAL 0 (add)
2 LOAD_FAST 0 (a)
4 LOAD_FAST 1 (b)
6 CALL_FUNCTION 2
8 RETURN_VALUE
How does LOAD_GLOBAL
convert add
into operator.__add__
? LOAD_GLOBAL
如何将add
转换为operator.__add__
? It clearly must save a reference to my_globals
somewhere inside itself or its __code__
object.. But I've been unable to find it.它显然必须在其自身或其
__code__
object 的某处保存对my_globals
的引用。但我一直无法找到它。
The reference you seek is the __globals__
attribute of the function object:您寻求的参考是 function object 的
__globals__
属性:
>>> result.__globals__
{'__name__': '__main__',
# Many lines omitted
'operator': <module 'operator' from '/usr/lib/python3.8/operator.py'>,
'code': 'lambda a, b: add(a, b)',
'add': <function _operator.add(a, b, /)>}
This attribute is documented in the Python Data model docs , under special attributes for user-defined functions:此属性记录在Python 数据 model 文档中,位于用户定义函数的特殊属性下:
__globals__
:__globals__
:
A reference to the dictionary that holds the function's global variables — the global namespace of the module in which the function was defined.对包含函数全局变量的字典的引用——定义 function 的模块的全局命名空间。
Read-only只读
As you found, the code object itself ( __code__
) does not contain a reference to the applicable globals dictionary.如您所见,代码 object 本身 (
__code__
) 不包含对适用的全局字典的引用。 This is explicitly mentioned in the data model docs under "code objects":这在“代码对象”下的数据 model 文档中明确提到:
Code objects represent byte-compiled executable Python code, or bytecode.
代码对象表示字节编译的可执行 Python 代码或字节码。 The difference between a code object and a function object is that the function object contains an explicit reference to the function's globals (the module in which it was defined), while a code object contains no context;
代码 object 和 function object 之间的区别在于function object 包含对函数全局变量(定义它的模块)的显式引用,而代码 object 不包含上下文; also the default argument values are stored in the function object, not in the code object (because they represent values calculated at run-time).
此外,默认参数值存储在 function object 中,而不是代码 object 中(因为它们表示在运行时计算的值)。 Unlike function objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects.
与 function 对象不同,代码对象是不可变的,不包含(直接或间接)对可变对象的引用。
globals
(and hence your my_globals
) is just a dictionary. globals
(因此你的my_globals
)只是一本字典。 It happens to be the default dictionary search for names at a global level, which LOAD_GLOBAL knows how to find.它恰好是全局级别的默认字典搜索名称,LOAD_GLOBAL 知道如何查找。 In your example, that master dictionary is your
my_globals
.在您的示例中,该主词典是您的
my_globals
。 You won't find a reference to it;您不会找到对它的引用; it's internal to the interpreter.
它在解释器内部。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.