from 《流畅的python》
def f1(a):
print(a)
print(b)
f1(3)
# NameError: name 'b' is not defined
def f1(a):
print(a)
print(b)
b = 5 # 全局变量
f1(3)
# 输出正常
python编译时,判断 b 是局部变量,因为在函数中给他赋值了 当打印 b 时,发现 b 没有绑定值,所以报错
b = 5
def f2(a):
print(a)
print(b)
b = 6 # 局部变量
f2(3) # UnboundLocalError: local variable 'b' referenced before assignment
b = 5
def f2(a):
global b
print(a)
print(b)
b = 6
print(b)
f2(3)
print(b)
输出 3, 5, 6, 6
def make_avg():
nums = [] # 自由变量
def averager(val): # 闭包延伸到函数的作用域之外,包含 nums 自由变量的绑定
nums.append(val) # list 是可变对象,我们没有赋值,只是调用 append
total = sum(nums)
return total/len(nums)
return averager
avg = make_avg()
print(avg(10)) # 10.0
print(avg(20)) # 15.0
print(avg(30)) # 20.0
# 报错 UnboundLocalError: local variable 'count' referenced before assignment
def make_avg():
count = 0 # 自由变量
total = 0
def averager(val):
count += 1 # int,str,元组等不可变元素,重新赋值,隐式创建局部变量
# 而不再是外部的自由变量, 不会保存在闭包中
total += val
return total/count
return averager
avg = make_avg()
nolocal
把变量标记为 自由变量,使用外层变量def make_avg():
count = 0
total = 0
def averager(val):
nonlocal count, total
count += 1
total += val
return total/count
return averager
avg = make_avg()
print(avg(10)) # 10.0
print(avg(20)) # 15.0
print(avg(30)) # 20.0