一句话解释:一个引用了外部变量的函数 . 或者说携带了额外作用域的函数
def out(s):
new_str = s * 2
def inner():
return new_str #自由变量, 下面解释
return inner
first = out("first")
second = out("second")
print("过了一段时间...")
print("给我第二次的值:" + second())
print("给我第一次的值:" , first())
深一点:
在1个内部函数中,对外部作用域的变量进行引用,但不包含全局作用域,即闭包
即上面的inner , 引用了外部变量new_str;
自由变量:定义在外部函数却由内部函数引用的变量 叫自由变量
自由变量存储在哪里?
存储在单元对象(cell)内,看下面例子
函数对象内的2个属性:
__closure__ , 包含了所有引用的变量(自由变量)
__code__ , 保存了局部变量名以及自由变量名
innerFunc = out("where am i?")
print(innerFunc.__closure__) #一个元组,包含所有的自由变量
print(innerFunc.__closure__[0].cell_contents) #new_str 拿出来看看
print(innerFunc.__code__.co_freevars) #看看被引用的变量名
注意坑:
def func():
x = 1
def innerFunc():
x = 2 #******这个是局部(本地)变量, 不在是自由变量, 因此不要出现 x+=1 赋值操作,会报错找不到本地变量,可以用locals()打印出来
return innerFunc
p = func()
print("---->:",p.__closure__)
print(p.__closure__[0].cell_contents)
print(p.__code__.co_freevars)
如果想让x成为自由变量, 或者使用x+=1:
def innerFunc():
nonlocal x
x += 1