前言:
今天小伙伴们对“闭包解决”都比较关注,我们都想要剖析一些“闭包解决”的相关内容。那么小编同时在网络上搜集了一些对于“闭包解决””的相关知识,希望同学们能喜欢,各位老铁们快快来学习一下吧!我也是自学的小白,看到这个名词之后我觉得我好像理解了,但是跟着实际操作之后仿佛又蒙了,这一刻我似乎想起了太极宗师张三丰问张无忌的那句话,你记住了嘛?
这一刻我既没记住名词的解释也没有看懂实例操作,终于在冲了好久的浪之后我给闭包整懂了。
什么样的函数能称之为闭包呢?只要有以下特征都可以称之为闭包:
一个函数中声明了另一个函数并返回,能够引用非全局变量的变量。
再让我们看看百度的说明,嗯好像比我说的更加简洁有力。
闭包就是能够读取其他函数内部变量的函数。
那么,这样在一个函数中声明另一个函数有什么好处呢?或者说任何一种概念被发明出来都是为了解决问题的,那么闭包这种行为解决了什么问题呢?
可以外部访问函数内部变量
内部函数可以访问外层函数变量
def 外层函数A():
a = "我是外层函数变量小a"
def 内层函数B():
nonlocal a
print(a)
return bar
x=foo()
x() #"我是外层函数变量小a"
局部变量可以常驻内存
#常驻内存了,对变量自加不会被清理
def 外层函数A():
a = 0
def 内层函数B():
nonlocal a
a+=1
print(a)
return bar
x=foo()
x() #1
x() #2
x() #3
x() #4
常驻的是局部变量,防止了污染变量命名
当然了有好处也有坏处,天下没有任何一门功夫是六边形的,他的缺点自然是:
会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
当然了,相对于抽象的说法和概念,在实际中闭包到底能解决什么问题呢?
下面以一个实例来看看闭包到底怎么解决问题的。
from threading import Timer
import time
# 定义总共输出几次的计数器
count = 0
def print_time():
print("当前时间:%s" % time.ctime())
global count
count += 1
# 如果count小于10,开始下一次调度
if count < 10:
t = Timer(1, print_time)
t.start()
# 指定1秒后执行print_time函数
t = Timer(1, print_time)
t.start()
上面的例子时一个简单计数器,每经过1秒,变量count便会+1,最终在count 小于10的时候进行重置。
发现这段代码的问题了吗,那就是使用了全局变量count,要说编程最最痛苦的事情之一就是变量命名,要信雅达可太难了,但是好名字是有限的,如果放在全局变量中那就很难受了,别人要是也有使用了这个变量的命名就会造成冲突。
那么如何使用闭包的概念对他进行改造呢
# 改闭包
# 定义总共输出几次的计数器
def time_count():
count = 0
def print_time():
nonlocal count #要么使用nonlocal声明变量不是本地的才可以有调用
#或者可以将count=[0] count[0]+=1 成为列表时为引用类型懂吧
print("当前时间:%s" % time.ctime())
print(count)
count += 1
# 如果count小于10,开始下一次调度
if count < 10:
t = Timer(1, print_time)
t.start()
return print_time
print_time=time_count()
# 指定1秒后执行print_time函数
t = Timer(1, print_time)
t.start()
看看,这就是闭包的好处,正常来说函数内部的变量用完就会被清理掉,但是有了闭包的存在,可以让函数内部的变量常驻,这样计数器进行计数就成为了可能,而且这还是一个局部变量不会污染全局。