经过多次试验和错误,我最终发现这不起作用:
def a():
def b():
print x
x=2
x = 1
b()
print x
你得到一个例外(x在被引用之前没有定义)。因此看起来b可以从x读取,但如果它试图分配给它,Python会将其对'x'的解释更改为局部变量,现在没有定义。
对我自己生病的好奇心的疑问:有没有办法实现这个目标?有没有办法显式访问父函数的范围? (x不是全球性的)
答案 0 :(得分:6)
Python 3中的nonlocal
statement将执行此操作。
编辑:在Python 2中,没有一种简单的方法可以做到这一点。如果您需要此功能,我建议您使用一些可变容器对象。例如:
def a():
def b():
print d["x"]
d["x"]=2
d = dict(x=1)
b()
print d["x"]
如果你绝对必须为CPython 2模拟nonlocal
,你可以用这种方式用Python C API来破解它:
import ctypes
import inspect
locals_to_fast = ctypes.pythonapi.PyFrame_LocalsToFast
locals_to_fast.restype = None
locals_to_fast.argtypes = [ctypes.py_object, ctypes.c_int]
def set_in_frame(frame, name, value):
frame.f_locals[name] = value
locals_to_fast(frame, 1)
def a():
def b(frame=inspect.currentframe()):
print x
set_in_frame(frame, "x", 2)
x = 1
b()
print x
你也可以设置本地框架,而不是调用PyFrame_LocalsToFast()
,你可以操纵a
的字节码,以便它使用LOAD_NAME
代替LOAD_FAST
。请不要做其中任何一件事。对于您的用例肯定有更好的解决方案。