开放封闭原则
讲装饰器之前我们先来了解一下开放封闭原则
开放封闭原则:软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。
装饰器的作用:
在不更改原功能函数内部代码,并且不改变调用方法的情况下为原函数添加新的功能。
@语法糖
def fun_a(func):
print('原方法返回值:',func())
return 'hello'
@fun_a # 这种写法,等价于 fun_b=fun_a(fun_b)
def fun_b():
return '123'
print(fun_b)
# 输出结果
# 原方法返回值: 123
# hello`
根据上例,我们可以看到,被@fun_a装饰的函数fun_b,不在是原来的函数了,而是被替换成fun_a()函数的返回值。即如果装饰器函数的返回值为普通变量,那么被修饰的函数名就变成了变量名;同样,如果装饰器返回的是一个函数的名称,怎么被修饰的函数名依然表示一个函数。
实际上,所谓函数装饰器,就是通过装饰器函数,在不修改原函数的前提下,来对函数的功能进行合理的扩充。
结合闭包函数实现装饰器
看下边的例子:
def fun_a(func): # fun_b函数的地址
def function():
print("函数执行前的操作")
res = func() # 调用fun_b函数
print("函数执行之后的操作")
return res # 返回fun_b()函数的返回值
return function # 返回闭包内层函数地址,方便用户调用
@fun_a # 这种写法,等价于 fun_b=fun_a(fun_b)
def fun_b():
print("执行fun_b函数")
fun_b() # 实际上执行的是装饰器内层函数function`
解析上述例子的执行逻辑:
- @fun_a语法糖,相当于把fun_b的地址当做参数给到fun_a函数的func变量;并执行fun_a函数,把内层函数的地址返回,此时fun_b存的是装饰器内层函数的地址
- fun_b() 相当于调用装饰器内层函数,先打印了
函数执行前的操作
- 然后执行了原来的fun_b函数,打印
执行fun_b函数
,并把该函数的返回值存到了res变量中 - 打印了
函数执行之后的操作
- 返回res
所以最终的执行结果如下:
函数执行前的操作
执行fun_b函数
函数执行之后的操作
网友评论