闭包
闭包存在的意义就是 保证数据的安全
闭包只能存在于嵌套函数中
内层函数对外层函数非全局变量的引用,就会产生闭包现象,被引用的非全局变量也称*变量,这个*变量会与内层函数产生一种绑定关系。
*变量不会在内存中消失。
闭包的作用:保证数据的安全。
闭包的注意事项:*变量不会被自动回收,消耗内存。
# 求累计平均数
def make_averager():
lis = [] # 外层非全局变量
def averager(num): # 内层函数
lis.append(num) # 内层函数对外层函数非全局变量的引用 这样就产生了闭包现象。
return sum(lis) / len(lis)
return averager
avg = make_averager()
print(avg(1000)) # 1000
print(avg(500)) # 750
print(avg(1000)) #833.3333333333334
装饰器
遵循 开放封闭原则
开放:对代码的拓展开放;
封闭:对源码的修改是封闭的;
在不改变原函数代码以及调用方式的前提下,为其添加新的功能。
如下实例,需求:在不改变 func1
函数调用方式及原代码的情况下;
使调用 func1
的打印结果为;
run
this is func1
end
def func1():
print("this is func1")
def wrapper(func):
def inner():
print("run")
func()
print("end")
return inner
func1 = wrapper(func1)
func1()
装饰器就是 重新定义一个函数,在这个函数里面调用原函数, 可以在调用原函数之前或者之后添加代码,最后将重新定义的函数名称替换成原函数名称。
入上图中的 7
8
9
分别是在原函数之前添加代码、调用原函数、在原函数后面添加代码。 上图中第 4
就是将 func1
这个变量指向到 wrapper
函数,而wrapper
函数又将 内层函数inner
返回给 func1
,所以此时调用 func1
就相当于调用 inner
函数。
小结:
- 重新定义一个函数
- 在这个函数里面调用原函数
- 将重新定义的函数名称替换成原函数名称
理解了上面的装饰器就来看下面的简化版本
上图中 @wrapper
这句代码就是将 func1
函数作为实参传递给 wrapper
, 同时 将func1
指向到 wrapper
函数,所以我们调用 func1
函数就相当于调用 wrapper
函数。
总结:
闭包:
- 闭包存在的意义就是 保证数据的安全
- 闭包只能存在于嵌套函数中
- 内层函数对外层函数非全局变量的引用,就会产生闭包现象,被引用的非全局变量也称*变量,这个*变量会与内层函数产生一种绑定关系。
- *变量不会在内存中消失。
装饰器
- 在不改变原函数代码以及调用方式的前提下,为其添加新的功能。
- 装饰器必须定义在被装饰函数的上方