闭包的定义(闭包的理解)

我也是自学的小白,看到这个名词之后我觉得我好像理解了,但是跟着实际操作之后仿佛又蒙了,这一刻我似乎想起了太极宗师张三丰问张无忌的那句话,你记住了嘛?

闭包的定义(闭包的理解)

这一刻我既没记住名词的解释也没有看懂实例操作,终于在冲了好久的浪之后我给闭包整懂了。

什么样的函数能称之为闭包呢?只要有以下特征都可以称之为闭包:

一个函数中声明了另一个函数并返回,能够引用非全局变量的变量。

再让我们看看百度的说明,嗯好像比我说的更加简洁有力。

闭包就是能够读取其他函数内部变量的函数。

那么,这样在一个函数中声明另一个函数有什么好处呢?或者说任何一种概念被发明出来都是为了解决问题的,那么闭包这种行为解决了什么问题呢?

  1. 可以外部访问函数内部变量
  2. 内部函数可以访问外层函数变量
    def 外层函数A():
        a = "我是外层函数变量小a"
        def 内层函数B():
            nonlocal a
            print(a)
        return bar    
    x=foo()
    x()  #"我是外层函数变量小a"
  3. 局部变量可以常驻内存
    #常驻内存了,对变量自加不会被清理
    def 外层函数A():
        a = 0
        def 内层函数B():
            nonlocal a
            a+=1
            print(a)
        return bar    
            
    x=foo()     
    x()   #1
    x()   #2
    x()   #3
    x()   #4
  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()

看看,这就是闭包的好处,正常来说函数内部的变量用完就会被清理掉,但是有了闭包的存在,可以让函数内部的变量常驻,这样计数器进行计数就成为了可能,而且这还是一个局部变量不会污染全局。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 xxx@163.com 举报,一经查实,本站将立刻删除。

发表评论

登录后才能评论