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

Can you assign to a variable defined in a parent function?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Python nested functions variable scoping

经过多次尝试和错误,我最终发现这行不通:

1
2
3
4
5
6
7
def a():
    def b():
        print x
        x=2
    x = 1
    b()
    print x

您会得到一个异常(X在被引用之前没有定义)。所以看起来b可以从x中读取,但是如果它试图分配给它,那么python将它对x的解释改为一个局部变量,而这个局部变量现在还没有定义。

关于我自己病态的好奇心的问题是:有什么办法可以做到这一点吗?是否有明确访问父函数范围的方法?(X不是全局的)


python 3中的nonlocal语句将做到这一点。

编辑:在Python2中,没有一种简单的方法可以做到这一点。如果您需要这个功能,我建议您使用一些可变容器对象。例如:

1
2
3
4
5
6
7
def a():
    def b():
        print d["x"]
        d["x"]=2
    d = dict(x=1)
    b()
    print d["x"]

如果您必须为c python 2模拟nonlocal,您可以使用python c api进行黑客攻击:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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。请不要做这两件事。对于您的用例,肯定有更好的解决方案。