python装饰器就是用于拓展原来函数功能的一种函数。
这个函数的特殊之处在于它的返回值也是一个函数。
使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能
1 最开始需求:打印函数工作
def f1():
print("This is function")
def f2():
print("This is a function")
2 需求变更:要求打印函数工作的基础上,在打印电气概念系统的时间
最简单的方式,就是在上面两个方法内增加一条打印时间的语句,该方法也是可行的
def f1():
print("This is function")
print(datetime.datetime.now()) #该datetime.datetime.now() 方法需要导入datetime模块
def f2():
print("This is a function")
print(datetime.datetime.now())
但是,如果项目不允许你直接修改原代码(往往修改原代码,在项目会打来意想不到的错误),怎么办?
方法有两种:
1.消耗内存的笨方法:
#不用装饰器对原有的代码进行修改
def f1():
print("This is function")
def f2():
print("This is a function")
#在上述方法上增加打印时间的需求
def print_datetime(func):
print(datetime.datetime.now())
#在执行之前的方法,通过传递参数的方式获取之前的方法并执行
func()
print_datetime(f1)
print_datetime(f2)
2.使用装饰器
#使用装饰器方法实现上述的业务
#使用类闭包的方式实现,并将之前的函数传给装饰器
#使用 @符号,释放装饰器的魅力
#装饰器编写
def decorator(func): #传入要在该方法基础上要实现的操作
def wrapper():
print(datetime.datetime.now()) #这是新需求要求增加的新要求
func() #执行之前的方法
return wrapper
@decorator #魅力之处,使用@符号加载装饰器,之后代码直接使用原方法即可,这对在原基础上修改代码非常奏效
def f1():
print("This is a origin function")
f1() #直接调用
3.业务再次增加,新增多个装饰器
#装饰器编写
def decorator(func): #传入要在该方法基础上要实现的操作
def wrapper():
print(datetime.datetime.now()) #这是新需求要求增加的新要求
func() #执行之前的方法
return wrapper
def decorator1(func): #新增加的业务需求,打印当前天气
def wrapper():
print("今天天气")
func()
return wrapper
@decorator #魅力之处,使用@符号加载装饰器,之后代码直接使用原方法即可,这对在原基础上修改代码非常奏效
@decorator1 #又增加一个业务需求的装饰器
def f1():
print("This is a origin function")
f1() #直接调用
Tips:装饰器执行顺序:从第一个装饰器开始,到最后一个装饰器,再执行函数本身