装饰器的本质就是闭包。
开放封闭原则
1.对扩展是开放的
为什么要对扩展开放呢?
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2.对修改是封闭的
为什么要对修改封闭呢?
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,
很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
带参数的装饰器。
import time def timer_out(flag1): #falg1 = flag def timer(f): def inner(*args, **kwargs): if flag1: start_time = time.time() time.sleep(0.3) ret = f(*args, **kwargs) end_time = time.time() print('执行效率%s' % (end_time-start_time)) return ret else: ret = f(*args, **kwargs) return ret return inner return timer flag = True @timer_out(flag) # 1,步 timer_out(flag) == timer 2,@与timer结合,变成你熟悉的装饰器 @timer def func1(): print(111) @timer_out(flag) def func2(): print(222) @timer_out(flag) def func3(): print(333) func1() func2() func3()
多个装饰器装饰一个函数
def wrapper1(func): # func = f函数名 def inner1(): print('wrapper1 ,before func') # 2 func() print('wrapper1 ,after func') # 4 return inner1 def wrapper2(func): # func = inner1 def inner2(): print('wrapper2 ,before func') # 1 func() # inner1() print('wrapper2 ,after func') # 5 return inner2 @wrapper2 # f = wrapper2(f) 里面的f新变量 = inner1 外面的f最新变量 = inner2 @wrapper1 # f = wrapper1(f) 里面的f函数名 外面的f新变量=inner1 def f(): print('in f') # 3 f() # inner2() ''' wrapper2 ,before func wrapper1 ,before func in f wrapper1 ,after func wrapper2 ,after func '''
函数的有用信息。
def login(username,password): ''' 此函数执行了用户名和密码两个参数,完成的是登陆的功能。 :param username:zhangyajie :param password:123 :return: ''' return print('登陆成功') print(login.__name__) print(login.__doc__)
装饰器的有用信息
def wrapper(f): def inner(*args,**kwargs): print(f.__name__) print(f.__doc__) ret = f(*args,**kwargs) return ret return inner @wrapper def login(username,password): ''' 此函数执行了 :param username: :param password: :return: ''' print('登陆成功') return True print(login.__name__) print(login.__doc__) login(1,2)
from functools import wraps def wrapper(f): @wraps(f) def inner(*args,**kwargs): '''执行函数之前''' ret = f(*args,**kwargs) '''执行函数之后''' return ret return inner @wrapper def login(username,password): ''' 此函数需要用户名,密码两个参数,完成的是登陆功能 :param username: 123 :param password: 123 :return: True 登陆成功 false 登陆失败 ''' a = 2 c = 4 print('登陆成功') return True print(login.__name__) print(login.__doc__) print(login(1,2)) for i in login.__dict__: print(i)