前言:

函数篇的重要知识点,为什么要使用闭包,就是在只能向函数传递一个参数时,定义的内部函数需要使用外部函数的值时,那么闭包是最好的选择。



闭包的理解

在Python这门语言中,函数内部还可以定义函数,如果内部函数使用了外层函数的变量,则会产生闭包。

简而言之:闭包的特点就是内部函数引入了外部函数的变量。在Python中支持将函数作为对象使用,可以将函数当做变量或返回值使用。那么有此特性的语言,一般都支持闭包。



闭包函数的使用

def func():
    x = '这是闭包函数'
    def inner():
        print(x) # 调用了外层函数x的变量

    return inner

f = func()  # 调用func后,返回了inner的函数对象,所以f = func() = inner
f() # 调用的就是inner()
# 这个f 可以反复使用

打印结果:
'这是闭包函数'

因为作用域的关系,在全局中就无法拿到函数变量及其内部函数。通常在需要其函数的值时才会将值进行return返回。那么同理,我们需要使用其内部函数时,也可以通过函数名将其作为返回值。

向闭包函数传参

重点:

闭包引用后的变量不会因为外部函数结束而被回收,而是会一直存在内存中,直到内部函数调用结束。

指的就是 自由变量(外部函数定义,却在内部函数被引用)。外部函数值在被闭包捕捉到以后,就可以脱离原来的作用域,被闭包所保存。

def func():
	x = [1]
	
	# 闭包函数
    def inner(y): # y接收传递进来的参数
		
		# 为啥可以改变外部列表往不属于自己局部的变量添加内容,那是因为元素是可变的
		# 但是不可以通过+号进行赋值,这算是python函数的一个坑了
		
    	x.append(y)	# 每次都往外层函数x列表里面增加参数
        
    return inner # 返回它的函数对象

f = func()	# 执行func
# f得到func的返回值 inner的函数对象 f = inner

f(10) # 向inner传递参数
打印:[1,10]

f(20)
打印:[1,10,20]
# 上次增加的值还在,也就是说原有的值并没有被回收,而是一直被保存在内存中

闭包是可以脱离原本作用域的存在



判断是否为闭包函数

我们可以通过函数名.__closure__ 在函数为闭包时,返回一个cell ,如果不是闭包函数则返回None

输出cell

def func():
    x = '这是闭包函数'
    def inner():
        print(x)
    # 打印这个inner这个函数是否为闭包
    print(inner.__closure__) # 打印结果:<cell at 0x7fef7167d760: str object at 0x7fef728f0110>
    return inner

f = func()
f()

输出None

def func():
    x = '这是闭包函数'
    def inner():
        print('未使用外部函数变量')
    print(inner.__closure__) # 打印结果:None
    return inner

f = func()
f()



技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点赞 收藏+关注 谢谢支持!