在 Python 中,变数的范围会影响到它在程式中的可见性以及生命周期。主要分为两大类:区域变数 (local variable) 和全域变数 (global variable)。但在开始说明前,先来说明什么是Python 的作用域 (Scope)

什么是作用域?

在 Python 中,作用域指的是一个变数名称有效的范围。简单来说,就是一个变数在程式码中的哪些地方可以被存取。

Python 的作用域类型

Python 的作用域主要分为以下几种:

  • Local 作用域: 函数内定义的变数,只在函数内有效。
  • Enclosing 作用域: 包含非局部(non-local)且非全域的变数,通常在嵌套函数中出现。
  • Global 作用域: 模组层级的变数,在整个模组中都有效。
  • Built-in 作用域: 包含 Python 内建的函数和名称,例如 print()、len() 等。

作用域的查找顺序

Python 在查找变数时,会按照以下顺序搜寻:

  • Local 作用域: 首先在当前函数内部查找。
  • Enclosing 作用域: 如果在局部作用域找不到,则向上一层作用域查找。
  • Global 作用域: 如果在前两层都找不到,则在全局作用域查找。
  • Built-in 作用域: 最后在内建作用域查找。
  • x = "global" # 全局变数

    def outer():
    y = "enclosing" # 包含作用域变数

    def inner():
    z = "local" # 局部变数
    print(x, y, z) # 输出:global enclosing local

    inner()

    outer()

    在上面的例子中:

    • x 是全局变数,可以在任何地方访问。
    • y 是包含作用域变数,只能在 outer 函数和 inner 函数中访问。
    • z 是局部变数,只能在 inner 函数中访问。

    区域变数 (local variable)

    定义: 在函数内部定义的变数称为区域变数。作用域: 仅在定义它的函数内有效。生命周期: 当函数执行完毕,区域变数就会被销毁。

    def my_function():
    x = 10 # x 是区域变数
    print(x)

    my_function()
    # 在函数外部尝试访问 x 会报错,因为 x 只在 my_function 内有效

    全域变数 (global variable)

    定义: 在函数外部定义的变数称为全域变数。作用域: 在整个程式中都有效,包括在函数内。生命周期: 从定义开始,直到程式结束。

    x = 20 # x 是全域变数

    def my_function():
    print(x) # 在函数内可以直接访问全域变数

    my_function()
    print(x)

    x = 10 # 全域变数

    def my_function():
    y = 20 # 区域变数
    print(x) # 可以访问全域变数
    print(y) # 只能在函数内访问

    my_function()
    print(x) # 可以访问全域变数
    print(y) # 会报错,因为 y 是区域变数,在函数外部无法访问

    在函数内修改全域变数:global 关键字

    为什么需要global关键字?一般来说,在函数内部,我们无法直接修改函数外部定义的全域变数。这是因为函数内部会创建一个新的命名空间,区域变数会优先于全域变数。

    然而,如果我们确实需要在函数内修改全域变数,就必须使用global关键字来明确告诉 Python 解释器,我们要操作的是全域变数,而不是创建一个新的区域变数。

    在函数内修改全域变数:直接修改会产生一个新的区域变数,并不会改变全域变数的值。要修改全域变数,需要使用global 关键字。

    globe_x = 10

    def change_global():
    global globe_x
    globe_x = 20

    change_global()
    print(globe_x) # 输出 20

    命名冲突: 如果区域变数和全域变数名称相同,在函数内部会优先使用区域变数。

    何时使用哪一种?

    • 区域变数:大部分情况下,应该优先使用区域变数,因为它们有助于将变数的作用范围限制在函数内,避免命名冲突,提高程式码的可读性。
    • 全域变数:某些情况下,需要在多个函数中共享数据,可以使用全域变数。但过多的全域变数会使程式码变得复杂,难以维护,因此应该谨慎使用。

    小结

    区域变数和全域变数是 Python 中非常重要的概念。理解它们的作用范围和生命周期,有助于写出更清晰、更易于维护的程式码。在一般情况下,应该优先使用区域变数,并尽量避免过多地使用全域变数。

    • 建议:尽量避免使用 global 关键字尽量避免使用过多全域变数,因为这会增加程式码的耦合性,使得程式难以测试和维护。如果需要在多个函数中共享数据,可以考虑使用类或模组来管理这些数据。在函数内部修改全域变数时,一定要谨慎,因为这可能会导致意想不到的副作用。

    使用 global 关键字会直接操作全域变数,修改后的结果会反映在程式的所有部分。

    • 替代方案: 如果需要在函数之间共享数据,可以考虑使用类、模组或函数的返回值来传递数据,而不是直接修改全域变数。