装饰器
什么是装饰器?
装饰器是一种设计模式,可以在不改变原来函数的基本功能的基础上,给原来的函数添加一些修饰的功能,作用是:可以降低代码的耦合度
装饰器的本质就是一个闭包,把一个函数作为参数
被装饰函数本身变成了装饰函数
被装饰函数名__name__
也变成了装饰函数的name名
简单的计算时间的装饰器
import time
def timer(func):
def wrap(*args,**kwargs):
t1 = time.clock()
result = func(*args,**kwargs)
t2 = time.clock()
print(t2)
return result
return wrap
@ timer
def foo(n):
x =1
for i in range(1,n+1):
x *=i
return x
a = foo(100)
print(foo(100))
被装饰函数本身变成了装饰函数
被装饰函数名__name__也变成了装饰函数的name名
In [53]: foo
Out[53]: <function __main__.timer.<locals>.wrap>
In [52]: foo.__name__
Out[52]: 'wrap'
装饰器类
import time
class B:
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
t1 = time.clock()
result = self.func(*args,**kwargs)
t2 = time.clock()
print(t2)
return result
@B
def foo(n):
x = 1
for i in range(1,n+1):
x *=i
return x
res = foo(10)
print(res)
多层装饰器
import time
# 多层装饰器
def deco1(func):
print("exec deco1")
def wrap1(*args,**kwargs):
print("执行了wrap1")
res = func(*args,**kwargs)
print("exit wrap1")
return res
print("退出了deco1")
return wrap1
def deco2(func):
print("exec deco2")
def wrap2(*args,**kwargs):
print("执行了wrap2")
res = func(*args,**kwargs)
print("exit wrap2")
return res
print("退出了deco2")
return wrap2
def deco3(func):
print("exec deco3")
def wrap3(*args,**kwargs):
print("执行了wrap3")
res = func(*args,**kwargs)
print("exit wrap3")
return res
print("退出了deco3")
return wrap3
@deco1
@deco2
@deco3
def foo(x,y):
return x**y
print("装饰过程结束")
print(foo)
n = foo(3,4)
print(n)
'''
#执行过程:
exec deco3
退出了deco3
exec deco2
退出了deco2
exec deco1
退出了deco1
装饰过程结束
<function deco1.<locals>.wrap1 at 0x000002403CC93D90>
执行了wrap1
执行了wrap2
执行了wrap3
exit wrap3
exit wrap2
exit wrap1
81
'''
'''
其实这个装饰过程,就是先执行了deco3(因为离的近),deco3执行完了后,foo已经变成了wrap3,这时开始执行deco2,deco2接收到的是wrap3,然后又将wrap3变成了wrap2,然后deco1开始执行这时又将wrap2变成了wrap1
wrap1执行,调用了wrap2,wrap2又调用了wrap3,wrap3执行完,又依次返回
'''
带参装饰器
import time
def timer(run_times):
def warp1(func):
def warp2(*args,**kwargs):
st = time.clock()
st1 = time.time()
for i in range(run_times):
result = func(*args,**kwargs)
et = time.clock()
et2 = time.time()
t3 = et2-st1
print("et为:{}".format(et))
print("t3为:{}".format(t3))
return result
return warp2
return warp1
@timer(100)
def jieChen(n):
x = 1
for i in range(1,n+1):
x *=i
return x
jieChen(1000)
retry 装饰器
import time
import random
class retry(object):
def __init__(self, max_retries=3, wait=0, exceptions=(Exception,)):
self.max_retries = max_retries
self.exceptions = exceptions
self.wait = wait
def __call__(self, func):
def wrapper(*args, **kwargs):
for i in range(self.max_retries + 1):
try:
result = func(*args, **kwargs)
except self.exceptions:
print("retey..")
time.sleep(self.wait)
continue
else:
return result
return wrapper
@retry(3,1,(ValueError))
def foo():
n = random.randint(-10,10)
if n>=0:
return n
else:
raise ValueError('n<0')
print(foo())