logo

该视频仅会员有权观看

立即开通课程「Python 入门」权限。

¥
199
/ 年

作用域(scope)是指变量的可见范围,决定了变量在程序的哪些部分可以被访问。Python 中主要有四种作用域:

  • 局部(Local)作用域
  • 封闭(Enclosing)作用域
  • 全局(Global)作用域
  • 内置(Built-in)作用域

在作用域中按名称去寻找对象(Python 中一切皆对象)时,会按照 LEGB 规则去查找。如果发生重名,也会按照 LEGB 规则,谁先被找到就用谁。

所谓 LEGB 规则,很简单,就是作用域查找顺序为:Local -> Enclosing -> Global -> Built-in

另外需要注意的是 Python 里是没有块级作用域(Block scope)的。

for i in range(10): pass print(i)

以上代码会打印出 9。如果有块级作用域,那么在 for 块结束后,就不应该能访问 i,而现在,会得到 i 的最后一个值。更糟糕的是,如果 range() 里是 0,那么 for 循环会直接退出,这时再 print(i),结果就是:

NameError: name ‘i’ is not defined

所以,虽然 Python 没有块级作用域,但是建议就当它有,不要在代码块以外,使用代码块内定义的东西,以避免混乱。

局部作用域(Local Scope)

局部作用域指函数内部的变量,仅在函数内部可见,函数外部无法访问,比如下面的示例:

def greet(): name = "Alice" # 局部变量 print(f"Hello, {name}") greet() print(name) # 出错,因为 name 在函数外不可见

在上面代码中 name 变量是在 greet 函数内部定义的,只能在函数内部访问,函数外部无法访问。

另外需要注意 Python 中不在局部作用域里的变量默认是只读的,如果试图围为其绑定一个新的值,Python 会认为是在当前的局部作用域里创建一个新的变量,而不是修改外部的变量。

x = 10 def func(): x = 20 # 创建了一个新的局部变量 x print(x) func() print(x) # 输出: 10

上面的这段代码中,func 函数内部的 x 是一个新的局部变量,不会影响外部的 x 变量。如果我们直接在函数内部修改 x 的值,会报错:

x = 10 def func(): # UnboundLocalError: cannot access local variable 'x' where it is not associated with a value x += 20 # 报错,因为 x 是只读的 print(x) func()

上面代码中我们在 func 函数内部修改 x 的值,会报错,因为在 func 函数内部的 x 现在相当于是一个局部变量,是只读的,无法修改。

封闭作用域(Enclosing Scope)

封闭作用域指嵌套函数中的外层函数作用域,内部函数可以访问外层函数的变量。

def outer(): x = "外层变量" def inner(): print(x) # 可以访问外层变量,x 就是封闭作用域 inner() outer()

inner 函数可以访问 outer 函数中的 x 变量。

全局作用域(Global Scope)

全局作用域指模块或脚本级别的作用域,整个模块或脚本中都可以访问全局变量。

x = "全局变量" def func(): print(x) # 访问全局变量 func() print(x) # 全局变量也可以在函数外部访问

x 是全局变量,可以在函数内外访问。

内置作用域(Built-in Scope)

内置作用域指 Python 提供的内置函数和变量(如 printlen 等)。

# 使用内置函数 len numbers = [1, 2, 3] print(len(numbers)) # 输出: 3

len 是 Python 的内置函数,所以可以在任何地方直接使用。

global 关键字

global 关键字用来声明一个全局变量。在局部作用域想要对全局作用域的全局变量(不可变类型)进行修改时,需要使用 global 关键字。当然对于可变数据类型(list、dict 等)可以直接引用而不用通过 global 关键字。

x = "全局变量" def func(): global x x = "修改后的全局变量" func() print(x) # 输出: 修改后的全局变量

使用 global 关键字在函数内部修改了全局变量 x

nonlocal 关键字

除了 global 关键字,Python 还提供了 nonlocal 关键字,用于在嵌套函数中修改封闭作用域中的变量。

def outer(): x = "外层变量" def inner(): nonlocal x x = "修改后的外层变量" inner() print(x) # 输出: 修改后的外层变量 outer()

这里我们使用 nonlocal 关键字在 inner 函数中修改了 outer 函数中的 x 变量。

了解作用域可以帮助我们避免变量名冲突,合理管理变量,希望大家能够通过这些例子,更好的理解作用域的概念和用法。