可以给父函数中定义的变量赋值吗?
可能重复的问题:
Python 嵌套函数的变量作用域
经过多次尝试和错误,我最终发现这样做是行不通的:
def a():
def b():
print x
x=2
x = 1
b()
print x
你会遇到一个异常(在引用之前没有定义 x)。所以看起来 b 可以读取 x 的值,但如果它试图给 x 赋值,Python 就会把 'x' 解释为一个局部变量,而这个局部变量现在是没有定义的。
出于我自己的好奇:有没有办法做到这一点?有没有办法明确访问父函数的作用域?(x 不是全局变量)
1 个回答
6
在Python 3中,nonlocal
语句可以实现这个功能。
编辑: 在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
。不过请不要这样做。这种方法肯定不是你用例的最佳解决方案。