1.函数:

函数定义时,,def func(),func是一个函数的名字,其实它只是一个变量的名字,此变量内部保存了函数所在位置的引用地址。 函数调用结束后,其内部的局部变量是不释放的。例如:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

def func(a=[]):
print(id(a))
print(a)
a.append(5)
print(id(a))

func()
func()
调试:两次调用函数func,但形参a的引用地址保持不变,但函数调用完毕后,其内部的局部变量(形参a)并没有释放。导致调用一次函数,a列表增加一个数据5
2.闭包概念:
闭包:封闭的包装,防止对象被外界影响。在python中,函数可以嵌套,内嵌的函数可以自由使用外部函数的局部变量。
如下:func1 函数即内嵌函数,变量a是自由变量。每次调用func1时,都需要调用a,将函数func1和变量a进行打包,这个过程称为闭包。
def func(a=[]):
  def func1():
  print(id(a))
  print(a)
  a.append(5)
  print(id(a))

 再举一例子,将闭包过程进行解释:

def func(i=[]):

def func1(a=[]):
print(id(a))
print(id(i))
a.append(5)
i.append(5)
print(a)
print(i)
print("----------")

return func1

b=func()
print(b())
c=func()
print(c())
调试结果:

10373720
10372560
[5]
[5]
----------
None
12569376
10372560
[5]
[5, 5]
----------

  闭包过程如下,每次调用func(),形成一个新的闭包,将func1和形参a=[],变量i(注意不是i=[])开辟一个新的空间,进行保存。打印结果有较大的差异。通过观察i和a数据的变化,可以发现非闭包函数func和闭包函数func1在内存中存储的差异。对于非闭包函数,其形参i在内存中的存储是i中存放了[]的引用地址,只存储一次即a=[],只执行一次,a中存放的地址是同一个。每次调用时,i均指同一个[]的地址。对于闭包函数,每次调用func,其形参a在内存中都存储一次[]的引用地址,即每次执行一次a=[].a中存放的引用地址完全不同注意。

同时我们也可以发现,闭包时自由变量i的指向引用地址是同一个。这是因为函数中的局部变量调用结束后,也不释放的缘故。

总结,闭包时,只打包函数和函数形参 ,外层的自由变量并没有进行打包。主要是因为,外层函数在定义时,已经在内存中开辟空间存储了自己的局部变量。这也验证了,闭包函数无法修改自由变量,只能进行引用。

3.为什么要有闭包?

    闭包最大的好处是封闭包装,防止被打扰。举个例子以解释这个封闭包装的概念:

def func():
a=[]
def func1():
a.append(1)
print(a)
return func1
b=func()
c=func()
print(b,c)
调试结果:12010960 12012120
func1是一个简单的闭包函数,其实b,c指向的便是func1.打印b,c所指向的func1的地址不相同。相当于有两个func1,互不干扰。在这里其实func函数将func1和a进行打包组成了闭包函数
,每次调用func函数,便形成一个不同的闭包函数。

4.装饰器中,被装饰的函数,如果想单独使用怎么使用?

1.函数的在内存中存储形式

2.函数的运行步骤:

3.函数中形参、实参存储机制

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄