然后给大家介绍的是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
'''
#多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身。