闭包

1.闭包定义

    外函数中定义内函数,内函数运用外函数的临时变量,外函数返回值是内函数的引用。构成了一个闭包。

    (内函数+外函数的临时变量)

2.引用与地址

  地址?有没有括号?

引用,即存地址。举个例子:a=1,内存中有个地方存了1,用变量名a存1所在内存位置的引用/地址。

函数名后无括号——表示地址/引用

函数名后有括号——表示调用函数

3.闭包存在的理由

函数结束时,会将临时变量的内存释放。使用闭包返回内函数时,外函数虽然已经结束,但临时变量依然有效。

4.内函数修改外函数的临时变量

外函数绑定给内函数的是局部变量,为了在内函数中修改这个局部变量的值,可以:

(1)关键字声明:在python3中用nonlocal关键字声明一个变量,表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。

(2)修改数据类型:在python2中没有nonlocal,将闭包变量改成可变类型数据,再进行修改。

def outer(a):
    b=10
    c=[a]#修改临时变量类型
    def inner():
        nonlocal b#没有这一句的话,b+=1会报错
        b+=1
        c[0]+=1
        print(b)
        print(c[0])
    return inner


result=outer(1)#result后面没括号,只是存地址,但不执行
result()#真正的调用函数

5.内函数可以传入新的外函数不能提供的变量,临时变量具能够保持其持久性

def outer(x):
     def inner(y):
         nonlocal x
         x+=y
         return x
     return inner


a = outer(10)
print(a(1))#11
print(a(3))#14

       重点关注a=outer(10)以及a(1),传入了两个参数:传入10作为x,传入1作为y,x的值虽然通过nonlocal可以修改,但每次开启内函数时x始终还是10,外函数的临时变量可被修改但每次开启内函数使用同一份临时变量

6.闭包的作用

(1)装饰器Decorator

(2)面向对象,面向接口

(3)单例模式

7.__closure__属性

定义一个元组用于保存闭包的所有外部变量

def outer(x,y):
     def inner():
         print(x,y)
     return inner


a = outer(10,20)
print(a.__closure__[0].cell_contents)#10
print(a.__closure__[1].cell_contents)#20
print(a.__closure__)#(<cell at 0x0000025488E7B4C8: int object at 0x0000000055846F00>, <cell at 0x0000025488E7B828: int object at 0x0000000055847040>)
print(a.__closure__[0])#<cell at 0x0000025488E7B4C8: int object at 0x0000000055846F00>

8.Python的namespace

 一共有三种 namespace,分别为:

local namespace: 作用范围为当前函数或者类方法
global namespace: 作用范围为当前模块
build-in namespace: 作用范围为所有模块
当函数/方法、变量等信息发生重名时,Python会按照 “local namespace -> global namespace -> build-in namespace”的顺序搜索用户所需元素,并且以第一个找到此元素的 namespace 为准。

同时,Python中的内建函数locals()和globals()可以用来查看不同namespace中定义的元素。

s = "string in global"
num = 99
def numFunc(a, b):
    num = 100
    print("print s in numFunc: ", s)#print s in numFunc:  string in global
    def addFunc(a, b):
        s = "string in addFunc"
        print("print s in addFunc: ", s)#print s in addFunc:  string in addFunc
        print("print num in addFunc: ", num)#print num in addFunc:  100
        print("locals of addFunc: ", locals())#locals of addFunc:  {'s': 'string in addFunc', 'b': 6, 'a': 3, 'num': 100}
        # print
        return "%d + %d = %d" % (a, b, a + b)
    print("locals of numFunc: ", locals())
    # locals of numFunc:  {'addFunc': <function numFunc.<locals>.addFunc at 0x000001A78F0A6A60>, 'b': 6, 'a': 3, 'num': 100}
    # print
    return addFunc(a, b)


numFunc(3, 6)
print("globals: ", globals())#globals:  {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001A78EE3B240>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/PycharmProjects/offer/try2.py', '__cached__': None, 's': 'string in global', 'num': 99, 'numFunc': <function numFunc at 0x000001A78ED42E18>}

 

 

参考网址:

https://www.cnblogs.com/Lin-Yi/p/7305364.html

https://www.cnblogs.com/cicaday/p/python-closure.html

http://python.jobbole.com/82296/

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值