关于python中闭包的理解和小例子
2018-03-13 14:09
337 查看
一.闭包
1.闭包的概念
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。在本质上,闭包是将函数内部和函数外部连接起来的桥梁1.1.如何理解闭包
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。1.2举个小例子例子1def parent():
msg = '局部变量'
def child():
print(msg) # 外部变量
return child # 返回的是函数,带外部变量的
if __name__ == '__main__':
p = parent()#此时p-->child
p() #然后调用p当程序执行到 p = parent()时,就是将返回值child也就是child()的引用赋给了p,p()就是调用了parent的内置函数child
例子2def my_sum(*arg): #定义一个求和的函数
print('in my sum')
return sum(arg)
def dec(func): #做判断
def in_dec(*arg):
print('in dec arg =', arg)
if len(arg) == 0: #判断长度是否是0
return 0
for val in arg:
if not isinstance(val, int): #判断参数是否为int型
return 0
return func(*arg)
return in_dec
my_sum = dec(my_sum) #此处返回函数 in_dec
#此处调用函数 in_dec(*arg) 传入参数后 return的func(*args)就是在上一步传入的my_sum 然后进入my_sum运算 return sum(arg)
print(my_sum(1, 2, 3, 4, 5))打印结果为:in dec arg = (1, 2, 3, 4, 5)
in my sum
15例子3passline = 60
def fun(var):
print('%x'%id(var)) #此处以16进制打印出var在内存中的位置
if var > passline:
print('pass')
else:
print('failed')
def in_fun():
print(var)
in_fun()
return in_fun
f = fun(89)
f()
print(f.__closure__) # 打印出f函数在内存中的位置结果如下:68d878e0pass8989(<cell at 0x0000000002467618: int object at 0x0000000068D878E0>,)可知var在内存中的地址和in_func的内存地址相同我们可以这样理解为在定义in_func的时候把var作为函数的属性来定义,函数属性的值为元组,不可变
2.闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在父调用后被自动清除。为什么会这样呢?原因就在于parent是child的父函数,而child被赋给了一个全局变量,这导致child始终在内存中,而child的存在依赖于parent,因此parent也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。2.1 举个小例子 例子1(惰性请求)def foo(msg):
def say():
print("hello" + str(msg))
return say
say = foo("志玲")
say()例子2(使用闭包保持状态)
def count_down(num): def next(): nonlocal num temp = num num -= 1 return temp return next if __name__ == '__main__': n = count_down(10) while True: # 每调用一次就会减少一次计数 value = n() print(value) if value == 0: break此时打印结果为10,9,8,7,6,5,4,3,2,1,0 通过闭包的方法保持状态
3.使用闭包的注意点
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成性能问题,甚至有可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
end.............
相关文章推荐
- 一段关于python 闭包的例子
- python中闭包和装饰器的理解(关于python中闭包和装饰器解释最好的文章)。
- javascript执行上下文、作用域与闭包(第七篇)---关于闭包典型例子的理解
- 关于Python闭包的理解
- 关于Python中闭包与装饰器的理解
- 关于js闭包自己的理解
- 关于js闭包的一些理解
- python if __name__ == '__main__':(有例子就是好理解)
- 关于Python的web模板jinja2的简单例子
- javascript执行上下文、作用域与闭包(第五篇)---一个例子的理解
- JavaScript高级程序设计 Chapter 7 关于函数、闭包的笔记和理解
- python open函数关于w+ r+ 读写操作的理解
- 『python思考』关于列表的浅复制和深复制的理解
- 理解神经网络,从简单的例子开始(1)7行python代码构建神经网络
- 关于Python2/3多进程的一些个人理解
- JS:关于我对闭包的理解
- 关于STM32中NVIC的理解,带错误例子
- 用一个简单的例子来理解python高阶函数
- 我写的关于python写nt服务的例子[zt]
- 深入理解python中闭包,闭包的实质