可以给父函数中定义的变量赋值吗?

2 投票
1 回答
2232 浏览
提问于 2025-04-17 06:33

可能重复的问题:
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。不过请不要这样做。这种方法肯定不是你用例的最佳解决方案。

撰写回答