CodeGym /课程 /Python SELF ZH /变量的作用域

变量的作用域

Python SELF ZH
第 6 级 , 课程 4
可用

10.1 函数的局部变量

在 Python 中,变量从创建的那一刻起到其作用域的结束都是可用的——通常这是 它所声明的函数。如果变量是在所有函数之外声明的,那么它被称为全局变量。

在 Python 中,变量的作用域决定了变量可被使用的上下文。作用域帮助 避免名称冲突并控制对数据的访问。Python 中主要的作用域类型包括:

局部作用域:在函数内创建的变量存在于该函数的局部作用域中,只能在其中使用。

嵌套函数的作用域:如果函数是在另一个函数内定义的,它的变量只能 在这个嵌套函数内部访问。

全局作用域:在脚本或模块级别定义的变量被视为全局变量,并且可以从同一模块的任何代码中访问。

内置作用域:这是一个特殊的作用域,包含所有 Python 默认可用的内置对象和 函数(例如,print() 和 len())。

LEGB 规则

为了解决变量,Python 使用 LEGB 规则,该规则定义了解释器寻找变量的顺序:

  • L (Local) — 首先在局部作用域中查找。
  • E (Enclosed) — 然后在所有嵌套函数的作用域中查找,从最近的到外部的。
  • G (Global) — 接下来在全局作用域中查找。
  • B (Built-in) — 最后在内置作用域中查找。

使用示例


x = "global"  # 全局变量

def outer():
    y = "outer local"  # 外部函数的局部变量
    def inner():
        z = "inner local"  # 内部函数的局部变量
        print(x)  # 输出 "global"
        print(y)  # 输出 "outer local"
        print(z)  # 输出 "inner local"
    inner()

outer()

变量 z 只能在函数 inner() 内使用。

变量 y 可以在函数 outer() 内及其内部声明的所有函数中使用。

变量 x 可以在当前文件(模块)的任何地方访问。

10.2 访问全局变量:global x

Python 的一个有趣特点是,外部作用域(当前作用域嵌套的作用域)中的变量只能读取

尝试对外部变量进行写入时,会创建一个同名的局部变量,从而失去对外部变量的访问。

示例:


x = 10

def change_global():
    print(x)  # 这会导致错误,因为 x 将在赋值后被视为局部变量
    x = 20  # 这里创建了一个局部变量 x
    print(x)  # 输出 20(访问局部变量 x)
        
change_global()
print(x)  # 输出 10

这个例子无法运行,会导致 UnboundLocalError 错误,因为 Python 解释器首先看到的是 x = 20 的赋值操作,认为 x 是一个局部变量。然而,当解释器到达 print(x) 时,找不到局部变量 x,因为它还没有被定义。

这样做是为了安全,以防止局部变量意外地更改全局变量。

操作符 global

如果需要在函数内部有意识地更改全局变量的值,可以使用 global 操作符。这允许明确表示更改的是全局变量而非局部变量。

要在函数内更改全局变量的值,必须在函数开头使用 global 声明该变量。这为函数提供了对变量的写访问权限:


x = 10

def change_global():
    global x  # 声明 x 是全局变量
    print(x)  # 输出 10(访问全局变量 x)
    x = 20  # 在此为全局变量 x 赋予新值
    print(x)  # 输出 20(访问全局变量 x)

change_global()
print(x)  # 输出 20

使用 global 操作符可以避免错误并正确管理全局变量。

全局变量可能会使程序不那么容易预测和难以理解,因为它们的值可以在程序的任何地方被更改。如果程序很大并由团队开发,这尤其关键。

虽然有时使用全局变量是不可避免的,但应该尽量减少它们的使用。相对于全局变量,考虑使用函数参数、返回值和类来保存状态。

使用全局变量可能导致意外的副作用,难以调试和测试代码,并降低代码的可重用性。因此建议谨慎使用全局变量,并且仅在确实必要时使用。

10.3 访问非局部变量:nonlocal

除了全局和局部变量,Python 中还有来自中间作用域的变量。比如,当一个函数嵌套在另一个函数中时。要处理这样的变量,可以使用 nonlocal 操作符。

nonlocal 操作符允许在嵌套函数中操作变量,改变其在最近的作用域中的值,但不包括全局变量。

nonlocal 操作符帮助避免在嵌套函数中创建新的局部变量,当需要改变定义在外部函数中的变量时。没有使用 nonlocal 的情况下,改变将只会影响内部函数的局部变量,而不会影响外部函数中的变量。

示例:


def outer():
    count = 0

    def inner():
        nonlocal count
        count += 1
        return count

    return inner

counter = outer()
print(counter())  # 输出 1

这是一个使用 nonlocal 创建计数器的更实际的示例:


def create_counter():
    count = 0
    
    def increment():
        nonlocal count
        count += 1
        return count
    
    return increment

counter = create_counter()
print(counter())  # 输出 1
print(counter())  # 输出 2
print(counter())  # 输出 3

这个例子展示了如何在实际情境下使用 nonlocal 来创建一个在调用间保持状态的函数。

2
任务
Python SELF ZH, 第 6 级, 课程 4
已锁定
使用全局变量
使用全局变量
2
任务
Python SELF ZH, 第 6 级, 课程 4
已锁定
使用 nonlocal 变量
使用 nonlocal 变量
评论 (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Anonymous #11681054 级别 1,Zurich,Switzerland
7 十月 2025
Enclosing | 外层函数 | 直接访问,修改用 nonlocal Global | 模块顶层 | 直接访问,修改用 global