- 闭包中对外部变量的引用和修改规则
- 引用规则:在闭包中,可以直接引用外部函数(非全局作用域)的变量。例如:
def outer():
x = 10
def inner():
print(x)
return inner
f = outer()
f()
- 修改规则:
- 不可变变量:对于外部函数中的不可变变量(如整数、字符串、元组等),在闭包函数中不能直接修改。如果尝试直接修改,会导致
UnboundLocalError
错误,因为Python会将其视为在闭包函数内部创建一个新的局部变量,而不是修改外部函数的变量。例如:
def outer():
x = 10
def inner():
x = 20 # 这里会报错,因为Python认为是在inner函数内创建新局部变量x,而不是修改outer函数的x
print(x)
return inner
f = outer()
f()
- **可变变量**:对于外部函数中的可变变量(如列表、字典等),可以在闭包函数中直接修改其内容,因为可变对象的内存地址不变,只是对象内部的值发生了改变。例如:
def outer():
my_list = [1, 2, 3]
def inner():
my_list.append(4)
print(my_list)
return inner
f = outer()
f()
- 闭包函数在按值调用环境下,试图修改外部不可变变量的情况
- 会发生
UnboundLocalError
错误。如上述修改不可变变量x
的代码示例,Python解释器会认为在闭包函数内部试图创建一个新的局部变量x
,而此时还没有对该局部变量赋值就使用,从而报错。
- 正确修改外部不可变变量的方法
- 使用
nonlocal
关键字(Python 3+):在闭包函数中,如果要修改外部(非全局)不可变变量,可以使用nonlocal
关键字。nonlocal
关键字用于声明变量来自外部函数的作用域,而不是全局作用域或当前函数的局部作用域。例如:
def outer():
x = 10
def inner():
nonlocal x
x = 20
print(x)
return inner
f = outer()
f()
- 原理:
nonlocal
关键字明确告诉Python解释器,在闭包函数中使用的变量是外部函数作用域中的变量,而不是创建一个新的局部变量。这样就可以在闭包函数中合法地修改外部不可变变量的值。