在嵌套函数中使用全局名称

ste*_*eve 3 python scope nested global python-2.7

据我了解以下代码中的全局语句,它应防止function_two重新绑定名称测试,而应在function_one中修改测试。但是,我得到NameError:全局名称'test'未定义。

def function_one():
    test = 1
    def function_two():
        global test
        test += 1
    function_two()
    print test
function_one()
Run Code Online (Sandbox Code Playgroud)

我已经看过,但找不到这样的例子。我想念什么?

Mar*_*ers 6

Python 2不支持non-local的概念。闭包(test从父函数访问)仅支持读取访问,而不支持Python 2中的赋值。

该global关键字确实意味着全球,如该名住在模块(全球)命名空间。function_one()函数的名称空间不是全局的,它是本地的(对于该函数)。

在Python 3中,您可以将名称标记为nonlocal,这将使您的示例按预期工作。请参阅PEP 3104- 访问外部作用域中的名称。

在Python 2中,您将不得不使用技巧。例如,使名称成为嵌套函数的属性。允许以封闭形式“读取”功能对象,也可以在此类封闭对象上设置属性:

def function_one():
    def function_two():
        function_two.test += 1

    function_two.test = 1
    function_two()

    print test
Run Code Online (Sandbox Code Playgroud)

另一个技巧是使用可变对象,例如列表或字典。同样,您只读取封闭的名称,然后直接更改结果对象:

def function_one():
    test = [1]

    def function_two():
        test[0] += 1

    function_two()

    print test[0]
Run Code Online (Sandbox Code Playgroud)