Ara*_*Fey 7 python global cpython function
我有一个dict像这样的子类:
class MyDict(dict):
def __getitem__(self, name):
return globals()[name]
Run Code Online (Sandbox Code Playgroud)
>>> eval('bytearray', MyDict())
<class 'bytearray'>
>>> exec('print(bytearray)', MyDict())
<class 'bytearray'>
Run Code Online (Sandbox Code Playgroud)
但是如果我用types.FunctionType构造函数实例化一个函数对象,该函数就无法访问任何内置函数:
import types
func = lambda: bytearray
func_copy = types.FunctionType(func.__code__,
MyDict(),
func.__name__,
func.__defaults__,
func.__closure__)
print(func_copy())
# Traceback (most recent call last):
# File "untitled.py", line 16, in <module>
# print(func_copy())
# File "untitled.py", line 8, in <lambda>
# func = lambda: bytearray
# NameError: name 'bytearray' is not defined
Run Code Online (Sandbox Code Playgroud)
替换MyDict()为globals()or dict(globals())或event {'__builtins__': __builtins__}会使代码<class 'bytearray'>按预期打印.
我不明白这个例外的来源.谁能解释这种行为?为什么它适用于eval但不适用于函数对象?
这不是一个完整的答案,但似乎发生的情况是 CPython__getitem__在访问内置函数时忽略了自定义。它似乎像一个普通的(没有子类的)字典一样对待MyDict。如果'__builtins__'密钥实际上存在于字典中,那么一切正常:
class MyDict(dict):
def __getitem__(self, name):
return globals()[name]
import types
globs = MyDict()
globs['__builtins__'] = __builtins__
func = lambda: bytearray
func_copy = types.FunctionType(func.__code__,
globs,
func.__name__,
func.__defaults__,
func.__closure__)
print(func_copy())
# output: <class 'bytearray'>
Run Code Online (Sandbox Code Playgroud)
问题仍然是为什么这只发生在FunctionType,而不是eval和上exec。
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |