装饰器概念
装饰器是闭包函数的一种应用场景。
强调装饰器的原则:1.不修改被装饰对象的源代码; 2.不修改被装饰对象的调用方式。
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能。
无参装饰器
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper @timmer def foo(): time.sleep(3) print('from foo') foo() 无参装饰器
代码执行流程为: 直接从 @timmer 说起,python解释器会为@后面的装饰器函数加()运行装饰器函数,timer函数的返回值是 wrapper 函数的内存地址,并将该内存地址赋值给foo变量,也就是foo函数的内存地址已经由原来的内存地址转换为 wrapper 函数的地址,此时如果打印 foo.__name__得到的也是 wrapper,之后对于foo的执行实际上是对 wrapper函数的执行。
含参装饰器
def auth(driver='file'):
def auth2(func):
def wrapper(*args,**kwargs):
name=input("user: ")
pwd=input("pwd: ")
if driver == 'file':
if name == 'egon' and pwd == '123':
print('login successful')
res=func(*args,**kwargs)
return res
elif driver == 'ldap':
print('ldap')
return wrapper
return auth2
@auth (driver='file')
def foo(name):
print(name)
foo('egon')
有参装饰器
代码执行流程为:从 @auth(driver='file') 说起,与无参装饰器相同,python解释器会为@后面的装饰器函数加()运行装饰器函数,返回auth2函数的内存地址,但是由于装饰器后面有 (driver='file') ,则携带着参数立刻执行auth2函数,返回wrapper函数的内存地址,将该地址赋值给foo函数,之后的代码流程与无参装饰器一致。