你能分配给父函数中定义的变量吗?

时间:2011-11-18 06:32:51

标签: python variables scope

  

可能重复:
  Python nested functions variable scoping

经过多次试验和错误,我最终发现这不起作用:

def a():
    def b():
        print x
        x=2
    x = 1
    b()
    print x

你得到一个例外(x在被引用之前没有定义)。因此看起来b可以从x读取,但如果它试图分配给它,Python会将其对'x'的解释更改为局部变量,现在没有定义。

对我自己生病的好奇心的疑问:有没有办法实现这个目标?有没有办法显式访问父函数的范围? (x不是全球性的)

1 个答案:

答案 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。请不要做其中任何一件事。对于您的用例肯定有更好的解决方案。