简体   繁体   English

已编译的 function 从哪里获取其 globals()?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM