在 Python 中,变量的作用域决定了变量在程序中的可见性和生命周期。Python 使用 LEGB 规则 来解析变量的作用域,按以下顺序查找变量:
- Local(局部作用域)
- Enclosing(闭包作用域/外层函数作用域)
- Global(全局作用域)
- Builtins(内置作用域)
以下是对每个作用域的详细说明:
1. Local(局部作用域)
-
定义:变量定义在函数或方法内部,仅在该函数内可见。
-
生命周期:仅在函数执行期间存在,函数退出后销毁。
-
示例:
def my_function(): x = 10 # 局部变量 print(x) my_function() # 输出: 10 print(x) # 报错: NameError, x 未定义 -
注意:
- 局部变量只能在定义它的函数内访问。
- 如果在函数内对变量赋值,Python 默认认为它是局部变量,除非显式声明为
nonlocal或global。
2. Enclosing(闭包作用域/外层函数作用域)
-
定义:在嵌套函数中,内层函数可以访问外层函数的变量(但不能直接修改,除非使用
nonlocal声明)。 -
适用场景:主要出现在函数嵌套的情况下,如闭包。
-
示例:
def outer_function(): x = 20 # 外层函数变量 def inner_function(): print(x) # 访问外层函数的 x inner_function() outer_function() # 输出: 20 -
修改 Enclosing 变量:
使用nonlocal关键字可以在内层函数中修改外层函数的变量。def outer_function(): x = 20 def inner_function(): nonlocal x x = 30 # 修改外层 x inner_function() print(x) outer_function() # 输出: 30 -
注意:
- Enclosing 作用域仅在嵌套函数中存在。
- 如果内层函数没有找到变量,会继续向外查找(Global、Builtins)。
3. Global(全局作用域)
-
定义:变量定义在模块(文件)级别,对整个模块可见。
-
生命周期:在模块加载期间存在,直到程序结束。
-
示例:
x = 100 # 全局变量 def my_function(): print(x) # 访问全局变量 my_function() # 输出: 100 print(x) # 输出: 100 -
修改全局变量:
在函数内修改全局变量需要使用global关键字。x = 100 def my_function(): global x x = 200 # 修改全局变量 my_function() print(x) # 输出: 200 -
注意:
- 全局变量可以在模块内的任何函数访问,但直接修改需要
global声明。 - 过多使用全局变量可能导致代码难以维护。
- 全局变量可以在模块内的任何函数访问,但直接修改需要
4. Builtins(内置作用域)
-
定义:Python 的内置作用域包含内置函数和对象(如
print、len、int等),在任何地方都可访问。 -
查找顺序:当变量在 Local、Enclosing 和 Global 作用域中未找到时,Python 会查找 Builtins 作用域。
-
示例:
def my_function(): print(len) # len 是内置作用域中的函数 my_function() # 输出: <built-in function len> -
覆盖 Builtins:
可以定义与内置名称相同的变量,但会遮蔽内置作用域中的名称(不推荐)。len = 42 # 覆盖内置 len print(len) # 输出: 42 # print(len("hello")) # 报错: int 对象不可调用 -
注意:
- 内置作用域是 Python 的最后一道防线,通常不需要显式操作。
- 避免使用内置名称(如
list、str)作为变量名,以免引起混淆。
LEGB 规则总结
Python 解析变量时按照以下顺序查找:
- Local:当前函数或块内的变量。
- Enclosing:外层函数的变量(如果有嵌套)。
- Global:模块级别的变量。
- Builtins:Python 内置的函数和对象。
示例(综合展示 LEGB):
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # 查找 Local: "local"
inner()
print(x) # 查找 Enclosing: "enclosing"
outer()
print(x) # 查找 Global: "global"
print(len) # 查找 Builtins: <built-in function len>
输出:
local
enclosing
global
<built-in function len>
注意事项
-
作用域冲突:
- 如果在函数内对变量赋值,Python 默认将其视为局部变量,除非使用
global或nonlocal声明。 - 示例(常见错误):
修复:使用x = 10 def my_function(): x = x + 1 # 报错: 未定义局部变量 x print(x) my_function()global:x = 10 def my_function(): global x x = x + 1 print(x) my_function() # 输出: 11
- 如果在函数内对变量赋值,Python 默认将其视为局部变量,除非使用
-
查找性能:
- LEGB 规则的查找顺序意味着局部变量访问最快,内置作用域最慢(但影响微乎其微)。
-
调试技巧:
- 使用
locals()查看当前局部作用域的变量。 - 使用
globals()查看全局作用域的变量。 - 使用
dir(__builtins__)查看内置作用域的内容。
- 使用
1481

被折叠的 条评论
为什么被折叠?



