Python “nonlocal“ 关键字笔记
·
1. nonlocal 是什么?
nonlocal 用于在嵌套函数中声明变量来自外层函数作用域(非全局),使得可以在内层函数中修改外层函数的变量。
def outer():
x = 10
def inner():
nonlocal x # 声明 x 来自外层函数
x = 20 # 现在可以修改外层函数的 x
inner()
print(x) # 输出:20
2. 什么时候需要使用 nonlocal?
① 重新赋值不可变对象
def outer():
count = 0 # 不可变对象
def increment():
nonlocal count # 必须使用!
count += 1 # 重新赋值不可变对象
return count
return increment
② 重新绑定可变对象
def outer():
lst = [1, 2, 3] # 可变对象
def inner():
nonlocal lst # 必须使用!
lst = [4, 5, 6] # 重新绑定到新的列表
inner()
print(lst) # [4, 5, 6]
3. 什么时候不需要使用 nonlocal?
① 只读取外层变量(不修改)
def outer():
x = 10
def inner():
print(x) # 只需要读取,不需要 nonlocal
inner()
② 修改可变对象的内容
def outer():
lst = [1, 2, 3] # 可变对象
def inner():
lst.append(4) # 修改列表内容,不需要 nonlocal
lst[0] = 100 # 修改元素,不需要 nonlocal
inner()
print(lst) # [100, 2, 3, 4]
4. 可变对象 vs 不可变对象
🔄 可变对象 (Mutable)
创建后内容可以被修改的对象:
- 列表
list:[1, 2, 3] - 字典
dict:{'a': 1} - 集合
set:{1, 2, 3} - 自定义对象:用户定义的类实例
🔒 不可变对象 (Immutable)
创建后内容不能被修改的对象:
- 数字:
int,float - 字符串
str:"hello" - 元组
tuple:(1, 2, 3) - 布尔值
bool:True,False - 冻结集合
frozenset
总结规则
| 操作 | 是否需要 nonlocal |
例子 |
|---|---|---|
| 读取变量 | ❌ 不需要 | print(x) |
| 修改可变对象内容 | ❌ 不需要 | lst.append(1), dict['key'] = value |
| 重新赋值不可变对象 | ✅ 需要 | x = 10, count += 1 |
| 重新绑定可变对象 | ✅ 需要 | lst = [1,2,3], dict = {'a': 1} |
简单记忆:只有使用 = 进行赋值操作时才需要 nonlocal,无论对象是可变的还是不可变的。
更多推荐
所有评论(0)