作用域规则
5.4 作用域规则
Python 查找变量的顺序:局部 → 外层函数 → 全局 → 内置。
LEGB 规则:Local(局部)、Enclosing(外层)、Global(全局)、Built-in(内置)。
只在读取变量时按 LEGB 顺序查找;赋值默认创建局部变量。
循环和 if 语句不创建新作用域,其中的变量在外部也能用。
💡 小项目全局变量没问题,大项目建议把相关函数和数据封装成类。
💡 列表、字典等可变对象,在函数内修改元素要小心,可能意外影响其他地方。
💡 养成好习惯:先定义后使用,全局变量用大写标记。
LEGB 查找顺序
嵌套函数中,内层函数可以读取外层和全局变量。
# ========================================
# 示例:LEGB 查找顺序
# 说明:Python 按 LEGB 顺序查找变量
# ========================================
global_var = '全局'
def outer():
outer_var = '外层'
def inner():
inner_var = '内层'
# 先找局部(inner_var),找不到找外层(outer_var)
print(inner_var) # 内层:找到
print(outer_var) # 外层:找到
print(global_var) # 全局:找到
inner()
# print(inner_var) # 错误!inner_var 是 inner 的局部变量
outer()
循环变量的作用域
循环和 if 不会创建新作用域,其中的变量外部可见。
# ========================================
# 示例:循环变量的作用域
# 说明:for 循环的变量在循环后还能用
# ========================================
for i in range(3):
print(i)
# i 在循环结束后仍然存在
print('循环外的 i =', i) # i = 2(最后一个值)
if True:
flag = True
print('if 外的 flag =', flag) # flag 也能用
列表在内外共享
修改列表/字典元素不需要 global,但重新赋值会创建局部变量。
# ========================================
# 示例:列表在内外共享
# 说明:列表是引用类型,函数内修改会影响全局
# ========================================
names = ['小明', '小红'] # 全局列表
def add_name():
names.append('小刚') # 修改原列表,不需要 global
print('修改前:', names)
add_name()
print('修改后:', names) # 列表被改变了
# 但赋值会创建局部变量,不会改变全局列表:
def reset():
names = ['新学生'] # 这是新局部列表,不影响全局
reset()
print('reset后:', names) # 还是原来的列表
⚠️ 常见错误与正确对比
❌ 错误写法
x = [1, 2]
def func():
x.append(3) # 看似修改全局,但会被当成局部
x = [4] # 这行导致 x.append 报错✅ 正确写法
x = [1, 2]
def func():
global x
x.append(3)
x = [4]📌 函数内对变量赋值后,该变量变成局部变量,导致前面也变成局部报错。
