学习装饰器前提需要了解高阶函数,函数嵌套,函数闭包
python函数装饰器,顾名思义就是装饰函数,为函数添加新功能的的一种方式。
为什么要使用装饰器呢?
因为函数在运行时,如果不使用装饰器对函数进行功能添加,需要修改函数源代码,这样修改无疑会增加程序的冗余和复杂性,也不便于程序员对其进行修改。使用装饰器,可以在不改变函数源代码和调用方式的前提下,使用语法糖@装饰器,对函数功能进行添加。
装饰器本质上就是一个函数。
我们使用一个简单的例子来实现:
import time #这是一个装饰器函数名为timer def timer(func):#将原函数(func)以参数形式传入装饰器函数 def wapper():#定义装饰函数wapper start_time=time.time() func()#调用原函数 stop_time=time.time() print("程序的运行时间为%s"%(stop_time-start_time)) return wapper#返回wapper函数给timer @timer#定义index=timer(index) def index(): time.sleep(2) print("这是一个测试程序") index()
以上是一个无参数装饰器,有时候我们需要用到带参数的装饰器,比如登录验证,
import time #这是一个装饰器函数名为timer def timer1(auth_type): print(auth_type)#打印auth_type值,方便自己查看程序流程 def timer(func):#将原函数(func)以参数形式传入装饰器函数 def wapper():#定义装饰函数wapper if auth_type=="file": start_time=time.time() func()#调用原函数 stop_time=time.time() print("程序的运行时间为%s"%(stop_time-start_time)) else: print("不知道你输入的是什么") return wapper#返回wapper函数给timer return timer#返回timer给timer1 @timer1(auth_type="file")#定义index=timer(index(auth_type)) def index(): time.sleep(2) print("这是一个测试程序") index()
在使用装饰器过程中我们发现原函数的源信息不见了,当我们需要原函数的返回值,在原函数处是无法返回也没有的,这就需要我们重新理解装饰器语法糖的作用,不难发现,原函数已经变为装饰器中的函数wapper
以下实例根据以上代码试验:
通过使用,我们发现原函数的元信息显示结果为none
@timer1(auth_type="file")#定义index=timer(index(auth_type)) def index(): """这是原函数信息""" time.sleep(2) print("这是一个测试程序") print(index.__doc__) #结果为none
经过试验,可以验证,被修饰函数的元信息在装饰器中添加会有效打印
def wapper():#定义装饰函数wapper """装饰器中的元信息"""
针对这种情况,我们可以使用functools.wraps wraps本身也是一个装饰器,他能把原函数的的元信息拷贝到装饰器中,使装饰器函数有原函数一样的源信息
from functools import wraps#调用工具 def timer1(auth_type): print(auth_type)#打印auth_type值,方便自己查看程序流程 def timer(func):#将原函数(func)以参数形式传入装饰器函数 @wraps(func)将该工具装饰器插入到装饰器函数正上方 def wapper():#定义装饰函数wapper
我们也可以定义多个装饰器给函数使用,需要注意的是装饰器的调用顺序
@a
@b
@c
def f()
这种装饰就等效于f=a(b(c(f)))
时间: 2024-10-14 03:03:23