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

时间:2015-12-29 20:07:44

标签: python python-2.7 scope nested global

我理解下面代码中的全局语句,它应该阻止function_two重新绑定名称test,而是修改function_one中的test。但是,我得到NameError:未定义全局名称'test'。

discard-document()

我看了,我找不到像这样的例子。我错过了什么?

1 个答案:

答案 0 :(得分:3)

Python 2不支持非本地的概念。闭包(从父函数访问test)仅支持读访问,而不支持Python 2中的赋值。

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

在Python 3中,您可以将名称标记为nonlocal,这样可以使您的示例按预期工作。请参阅PEP 3104 - Access to Names in Outer Scopes

在Python 2中,你不得不求助于技巧。例如,使名称成为嵌套函数的属性。允许'读取'函数对象作为闭包,就像在这样的闭合对象上设置属性一样:

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

    function_two.test = 1
    function_two()

    print test

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

def function_one():
    test = [1]

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

    function_two()

    print test[0]