装饰器学习笔记2:闭包

额,我的拖延症(⊙﹏⊙)b,继续

2.闭包

python中一切都是对象,那么,参数和返回值都可以为函数

def func():
    class_num = 5
    def inner():
        age = 20
        print(class_num,age)
    return inner

 执行func()函数时,返回值是一个函数,那么如果想获取inner函数的结果,理论上如下方法执行

>>> a = func()
>>> a()

 这时发现了奇怪的问题,诶?执行a()时,相当于执行一个独立的inner()函数,
 inner内不含有变量class_num,class_num也不是全局变量.
 根据python的运行机制,当a=func()之后,a获得了返回值,理论上这时函数func()已经结束,变量class_num已销毁.
 执行inner()即a()时,和下面单独inner()函数执行一样,应无法获取到变量class_num,结果导致报错,例如这样:

def inner():
    age = 20
    print(class_num,age)
>>> inner()
NameError: name 'class_num' is not defined

但实际上并没有报错,执行结果是正确的,a()成功取到了已销毁的父级局部变量class_num

>>> a = func()
>>> print(a)
<function func.<locals>.inner at 0x7f08e00f3b70>
>>>a()
5 20

那么再实验下
添加一个全局变量class_num,发现内部inner并没有受到影响,inner()取得的变量class_num值仍是父级的局部作用域中的class_num

>>> class_num = 6
>>> a()
5 20

结论:
 a()执行时,相当于执行func()函数的内部函数inner().

 inner()在作为一个值返回时,包含了它的上级局部作用域,
 即,内部函数的局部作用域中可以访问外部函数局部作用域,
 也就是LEGB中的E级,嵌套的父级函数的局部作用域
 类似的这种情况,就是闭包.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值