软件开发中有一条非常重要的规则就是:对修改封闭,对扩展开放。
对于一个现有的函数,如果想要增强此函数的功能,但是不允许修改此函数源代码的时候,使用装饰器来解决这个问题
- 本质:就是一个闭包,还是一个返回函数的高阶函数
- 好处:就是在不用修改原函数代码的前提下给函数增加新的功能
1 装饰器写法
#被修饰的函数
def say_hello(name):
print('我就是人见人爱,花见花开的%s'%name)
# 参数是被修饰函数
def wrapper(func): #1.定义装饰器
def inner(name): #2.定义闭包 在闭包中增加功能
print('-' * 50)
func(name) #3.调用原函数实现原来的功能
print('*' * 50)
return inner #4.返回增强功能的函数
say_hello = wrapper(say_hello) #5.获取增强功能的函数
say_hello('风流小王子') #6. 调用增强函数,实现功能
2 @语法糖
使用@语法糖将装饰器应用到指定函数上,简化装饰器的写法
#用法:在需要被装饰的函数前面加上: @装饰器的名字 【外层函数的名字】
def wrapper(func):
def inner(age1):
#增加的功能
if age1 < 0:
age1 = 0
#调用原函数
func(age1)
return inner
@wrapper #相当于 getAge = wrapper(getage)
def getAge(age):
print(age)
getAge(18) #调用增强的函数
注意:使用@的时候,如果装饰器和需要被装饰的函数在同一个.py文件中的时候,装饰器一定要出现在被装饰函数的前面【Python中的代码是从上往下依次执行的】
3 带有不定长参数的装饰器
同一个装饰器可以应用于多个函数
def wrapper(func):
def inner(*tup,**kw): #变长参数
func(*tup,**kw)
print('-'*50)
return inner
@wrapper
def test1(a,b):
print(a,b)
test1(1,2)
@wrapper
def test1(a):
print(a)
4 多个装饰器作用在一个函数上
#多个装饰器同时作用于一个函数的时候,要注意一下装饰器执行顺序
def wrapper1(func):
print("wrapper1~~~~外部函数")
def inner(a,b):
print('wrapper1-----内部函数')
func(a,b)
return inner
def wrapper2(func):
print("wrapper2~~~~外部函数")
def inner(a, b):
print("wrapper2~~~~内部函数")
func(a, b)
return inner
@wrapper1
@wrapper2
def text(num1,num2):
print(num1 + num2)
text(10,20)