然后给大家介绍的是Wrapper(装饰器),使用广泛。python笔试,面试的话也会百分百问到的,基础和中级的知识储备还是必用的。
让我们开始。
先来一些基础相关知识
*args,**kwargs的区别 def function(x,y,*args,**kwargs): print(type(x)) print(args) print(kwargs) print(type(args)) print(type(kwargs)) function(1,2,3,4,5,a=1,b=2,c=3) <type 'int'> (3, 4, 5) #*args返回的是数组
{'a': 1, 'c': 3, 'b': 2} #**kwargs返回的字典
<type 'tuple'>
<type 'dict'>
正题开始
固定模板
装饰器:wrapper 模板: def 装饰器名(func): #def 与 @之后的函数名称一致 调用函数func与ret=func(*args,**kwargs)内部函数一致
def wrapper(*args,**kwargs): #def 与 return 之后的函数名称一致
ret = func(*args,**kwargs) return ret #return ret 与 ret=func(*args,**kwargs)一致
return wrapper @装饰器名 def foo(): pass
import time def timmer(fun1): def wrapper(*args,**kwargs): start_time=time.time() res=fun1(*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') @timmer def foo1(): time.sleep(5) print('from foo1') foo() foo1()
@wraps:避免被装饰函数自身的信息丢失
未添加@wraps
#-*- coding:utf-8 -*-
def decorator(func): def inner_function(): pass
return inner_function @decorator def func(): pass
print(func.__name__) #inner_function
添加@wraps
from functools import wraps def decorator(func): @wraps(func) def inner_function(): pass
return inner_function @decorator def func(): pass
print(func.__name__) #func #@wraps:避免被装饰函数自身的信息丢失
多个装饰器的同时使用
def makebold(f): return lambda:'<b>'+f()+'</b>'
def makeitalic(f): return lambda:'<i>'+f()+'</i>'
def makeitalic1(f): return lambda:'<strong>'+f()+'</strong>' @makebold @makeitalic1 @makeitalic def say(): return 'hello'
print(say()) #<b><strong><i>hello</i></strong></b> #多个装饰器的执行顺序:是从近到远依次执行。
类装饰器
#类装饰器
class Decorator(object): def __init__(self, f): self.f = f def __call__(self): print("decorator start") self.f() print("decorator end") @Decorator def func(): print("func") func() ''' decorator start func decorator end '''
import time def decorator(func): def wrapper(*args,**kwargs): start_time = time.time() func(*args,**kwargs) end_time = time.time() print(end_time - start_time) return wrapper class Method(object): @decorator def func(self): time.sleep(0.8) p1 = Method() p1.func() # 函数调用
''' 0.815999984741 对于类方法来说,都会有一个默认的参数self,它实际表示的是类的一个实例,所以在装饰器的内部函数wrapper也要传入一个参数 - me_instance(任意参数)就表示将类的实例p1传给wrapper,其他的用法都和函数装饰器相同。 '''
较为复杂的多个装饰器
import time def deco01(func): def wrapper(*args, **kwargs): print("this is deco01") startTime = time.time() func(*args, **kwargs) endTime = time.time() msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs) print("deco01 end here") return wrapper def deco02(func): def wrapper(*args, **kwargs): print("this is deco02") func(*args, **kwargs) print("deco02 end here") return wrapper @deco01 @deco02 def func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b)) if __name__ == '__main__': f = func f(3,4) ''' this is deco01 this is deco02 hello,here is a func for add : result is 7 deco02 end here time is 1032 ms deco01 end here '''
#多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身。