rba*_*ros 3 python dictionary namespaces subclass exec
我正在尝试将字典子类化以用于 exec 方法。最终,我希望本地函数具有自定义名称范围行为。
在下面的代码中,函数b()实际上有正确的globals()字典可用,但是在解析z.
函数b()先不搜索locals()然后globals()呢?
非常令人费解。任何帮助表示赞赏。
t = '''
def b():
# return (globals()['z']) #works
return z #fails
b()
'''
class MyDict(dict):
def __init__(self, g):
dict.__init__(self)
self.my_g = g
def __getitem__(self, key):
print("GET ", key)
try:
val = dict.__getitem__(self, key)
except:
print("GET exception1")
val = self.my_g[key]
return val
g = {'z':123}
md = MyDict(g)
#fails to find z
exec(t, md, md)
#works
#exec(t, g, g)
Run Code Online (Sandbox Code Playgroud)
GET b
Traceback (most recent call last):
File "/project1/text12", line 31, in <module>
File "<string>", line 6, in <module>
File "<string>", line 4, in b
NameError: global name 'z' is not defined
Run Code Online (Sandbox Code Playgroud)
在 python 3.3 之前,不能dict为globalsexec 语句的值使用自定义子类。执行编译代码的底层 C 代码直接访问底层 C 结构,忽略您可能已实现的任何自定义钩子。
换句话说,当代码执行LOAD_GLOBAL操作时(就像z您的函数中的情况b),C 字节码评估循环globals使用C API访问当前帧中的结构,绕过任何 python 覆盖。
这在exec()功能文档中记录为:
如果只提供globals,它必须是一个字典,它将用于全局和局部变量。如果给出了globals和locals,则它们分别用于全局变量和局部变量。如果提供,locals可以是任何映射对象。
此限制已在 Python 3.3 中放宽,请参阅issue 14385。文档尚未更新,但字节码评估循环已更新,以在回退到 C API 访问之前测试自定义映射。如果使用自定义映射,则使用该PyObject_GetItem函数,该函数将调用__getitem__自定义类。
| 归档时间: |
|
| 查看次数: |
898 次 |
| 最近记录: |