【问题标题】:Using global name in a nested function在嵌套函数中使用全局名称
【发布时间】:2026-02-10 18:10:01
【问题描述】:

据我了解下面代码中的全局语句,它应该防止 function_two 重新绑定名称 test,而是修改 function_one 中的 test。但是,我得到 NameError: global name 'test' is not defined。

def function_one():
    test = 1
    def function_two():
        global test
        test += 1
    function_two()
    print test
function_one()

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

【问题讨论】:

  • 你误会了。 globalnonlocal 的含义不同(仅限 Python 3)。 global 真正的意思是 global,例如不在函数中test in function_two 期望有一个全局名称 testfunction_one() 中的本地名称 test 被忽略。
  • 您使用的是 Python 2 还是 Python 3?大概是 Python 2,因为您使用 print 作为语句。
  • @name_no:不,那行不通。你会得到一个UnboundLocalError: local variable 'test' referenced before assignment 异常。
  • 是的,它是没有目的的代码。我只是想要一个简单的例子来证明我对全局语句的困惑。答案很有启发性。

标签: python python-2.7 scope nested global


【解决方案1】:

Python 2 不支持 non-local 的概念。闭包(从父函数访问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]

【讨论】: