编译后的函数从哪里得到它的 globals()?
Where does a compiled function get its globals()?
我发现如果我这样写:
code = f"lambda a, b: add(a, b)"
my_globals = globals().copy()
my_globals['add'] = operator.__add__
result = eval(code, my_globals, {})
然后 result(3, 5)
的值为 8,就像我想要的那样。
当我查看 result
的反汇编时,我看到:
0 LOAD_GLOBAL 0 (add)
2 LOAD_FAST 0 (a)
4 LOAD_FAST 1 (b)
6 CALL_FUNCTION 2
8 RETURN_VALUE
LOAD_GLOBAL
如何将add
转换成operator.__add__
?它显然必须在其自身或其 __code__
对象的某处保存对 my_globals
的引用。但我一直无法找到它。
您查找的参考是函数对象的__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, /)>}
此属性记录在 Python Data model docs 中,在 user-defined 函数的特殊属性下:
__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.
Read-only
如您所见,代码对象本身 (__code__
) 不包含对适用的全局字典的引用。这在“代码对象”下的数据模型文档中明确提到:
Code objects represent byte-compiled executable Python code, or bytecode. 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; also the default argument values are stored in the function object, not in the code object (because they represent values calculated at run-time). Unlike function objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects.
globals
(因此您的 my_globals
)只是一本字典。它恰好是全局级别的默认字典搜索名称,LOAD_GLOBAL 知道如何查找。在您的示例中,主词典就是您的 my_globals
。您不会找到对它的引用;它在解释器内部。
我发现如果我这样写:
code = f"lambda a, b: add(a, b)"
my_globals = globals().copy()
my_globals['add'] = operator.__add__
result = eval(code, my_globals, {})
然后 result(3, 5)
的值为 8,就像我想要的那样。
当我查看 result
的反汇编时,我看到:
0 LOAD_GLOBAL 0 (add)
2 LOAD_FAST 0 (a)
4 LOAD_FAST 1 (b)
6 CALL_FUNCTION 2
8 RETURN_VALUE
LOAD_GLOBAL
如何将add
转换成operator.__add__
?它显然必须在其自身或其 __code__
对象的某处保存对 my_globals
的引用。但我一直无法找到它。
您查找的参考是函数对象的__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, /)>}
此属性记录在 Python Data model docs 中,在 user-defined 函数的特殊属性下:
__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.
Read-only
如您所见,代码对象本身 (__code__
) 不包含对适用的全局字典的引用。这在“代码对象”下的数据模型文档中明确提到:
Code objects represent byte-compiled executable Python code, or bytecode. 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; also the default argument values are stored in the function object, not in the code object (because they represent values calculated at run-time). Unlike function objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects.
globals
(因此您的 my_globals
)只是一本字典。它恰好是全局级别的默认字典搜索名称,LOAD_GLOBAL 知道如何查找。在您的示例中,主词典就是您的 my_globals
。您不会找到对它的引用;它在解释器内部。