ZetCode

Python Nonlocal 关键字

最后修改于 2025 年 2 月 25 日

Python 中的 nonlocal 关键字允许嵌套函数修改来自封闭函数作用域的变量。本教程涵盖其用法、与 global 的区别以及在管理封闭作用域变量中的实际应用。

global 不同,nonlocal 针对最近的封闭作用域中的变量,但不包括全局变量。它允许对外部函数变量进行可变访问,而无需使用全局作用域,从而在嵌套结构中促进更清晰的封装。

修改封闭作用域变量

此示例展示了 nonlocal 如何修改来自封闭函数作用域的变量。

modify_enclosing.py
def outer():
    count = 0
    def inner():
        nonlocal count
        count += 1
        return count
    return inner()

result = outer()
print(result)  # Output: 1

nonlocal 声明允许 inner 修改来自 outer 作用域的 count。 如果没有它,Python 会将 count 视为 inner 的局部变量,从而导致错误。

嵌套函数作用域链

此示例演示了 nonlocal 如何通过多个嵌套级别访问变量。

multi_level.py
def level1():
    value = 10
    def level2():
        def level3():
            nonlocal value
            value *= 2
        level3()
        return value
    return level2()

print(level1())  # Output: 20

level3 中的 nonlocallevel1 访问 value,跳过 level2 的作用域。这展示了 nonlocal 如何向上搜索作用域层级,直到找到目标。

Nonlocal vs Local vs Global

此示例比较了不同关键字的变量作用域行为。

scope_comparison.py
global_var = 100

def outer_func():
    enclosing_var = 50
    def inner_func():
        local_var = 10
        nonlocal enclosing_var
        global global_var
        enclosing_var += 1
        global_var += 1
        return (local_var, enclosing_var, global_var)
    return inner_func()

print(outer_func())  # Output: (10, 51, 101)

nonlocal 修改 enclosing_var,而 global 影响 global_var。像 local_var 这样的局部变量仍然限制在其函数中。

带 Nonlocal 的有状态闭包

此示例创建了一个计数器工厂,使用 nonlocal 来维护调用之间的状态。

closure_counter.py
def make_counter():
    total = 0
    def counter():
        nonlocal total
        total += 1
        return total
    return counter

c = make_counter()
print(c(), c(), c())  # Output: 1 2 3

每次调用 c() 都会增加保存在闭包中的 totalnonlocal 允许状态保留,而无需类结构或全局变量。

使用类避免 Nonlocal

此示例使用类而不是 nonlocal 来实现类似的功能。

class_counter.py
class Counter:
    def __init__(self):
        self.total = 0
    
    def increment(self):
        self.total += 1
        return self.total

c = Counter()
print(c.increment(), c.increment())  # Output: 1 2

类属性为复杂场景提供更清晰的状态管理,减少对嵌套函数和 nonlocal 声明的依赖。

Nonlocal 使用的最佳实践

来源

Python Nonlocal 关键字文档

本教程探讨了 nonlocal 关键字在 Python 作用域管理中的作用,展示了实际用例和用于简洁代码的替代方案。

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程