Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 你能给父函数中定义的变量赋值吗?_Python_Variables_Scope - Fatal编程技术网

Python 你能给父函数中定义的变量赋值吗?

Python 你能给父函数中定义的变量赋值吗?,python,variables,scope,Python,Variables,Scope,可能重复: 经过多次尝试和错误,我最终发现这是行不通的: def a(): def b(): print x x=2 x = 1 b() print x 您将得到一个异常(在被引用之前未定义x)。看起来b可以从x中读取数据,但如果它试图赋值给它,Python会将其对“x”的解释更改为局部变量,而该变量现在还没有定义 我自己病态好奇的问题是:有什么方法可以实现这一点吗?是否有明确访问父函数范围的方法?(x不是全局的)Python

可能重复:

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

def a():
    def b():
        print x
        x=2
    x = 1
    b()
    print x
您将得到一个异常(在被引用之前未定义x)。看起来b可以从x中读取数据,但如果它试图赋值给它,Python会将其对“x”的解释更改为局部变量,而该变量现在还没有定义

我自己病态好奇的问题是:有什么方法可以实现这一点吗?是否有明确访问父函数范围的方法?(x不是全局的)

Python 3中的将实现这一点


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

def a():
    def b():
        print d["x"]
        d["x"]=2
    d = dict(x=1)
    b()
    print d["x"]
如果您绝对必须为CPython 2模拟
非本地
,那么您可以用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\u LocalsToFast()
,您可以操纵
a
的字节码,以便它使用
LOAD\u NAME
而不是
LOAD\u FAST
。请不要做这两件事。对于您的用例,肯定有更好的解决方案。

重复的,除其他外,是的,您的解释是正确的,Pyhton根据函数体中是否有赋值来更改其对“x”的解释。至于答案,正如MichaelHoffman所说,在Python3中可以使用“non-local”语句。太好了,谢谢。我确实搜索过类似的问题,但没有找到那个问题……这意味着,Python2.x中没有任何东西允许这样做。不容易!尽管有几种不同的方法可以做到这一点。请看我上面的编辑。哇,编辑得很好:)我认为什么算赋值给变量的概念有点微妙。在我的例子中,确实不需要做这些事情(外部函数实际上不需要修改值),但是知道这些是有用的。