看了《流畅的Python》,真是受益匪浅。
例如下面这个例子,看上去像是一个正常的闭包,但调用之后却会报错。
def make_averager():
count = 0
total = 0
def averager(new_value):
count += 1
total += new_value
return total / count
return averager
avg = make_averager()
avg(10)
# UnboundLocalError: local variable 'count' referenced before assignment
原因就在于前文提到的 python作用域。在内部函数中,有对变量count 赋值的行为,因此python认为这个是局部变量,并不会去外面找,因此不会被保存在闭包中。
这时候,想让count保存在闭包中,需要使用 nonlocal 关键字对变量进行声明,这时候 count就变为了自由变量,能够存在闭包中。
值得注意的是,如果是可变的对象,例如列表在内部调用 append 方法,并不会认定该列表为局部变量,因为这不是赋值操作。所以,在python 2.x 没有 nonlocal 关键字的情况下,可以将count 存储为可变对象(例如字典或者简单的实例)的元素或属性,实现不可变类型的闭包处理。
网友评论