在学习的时候发现直接调用装饰器可以很方便接入查询时间的函数
from cal_time import *
@cal_time
def quick_sort(li):
"""
data
"""
quick_sort(li)
# 这样就很方便
所以怎么才能使用装饰器呢
1.首先装饰器可以调用time函数,然后直接在方法上面加入@就行
import time
def show_time(func):
def wrapper():
star = time.process_time()
func()
end= time.process_time()
print('spend_time:',end-star)
return wrapper
@show_time
def func():
print('test')
func()
这是一种方法调用可以使用show_time的装饰器进行修饰
2.其外还可以传入参数。直接传入wrapper当中。
import time
def show_time(func):
def wrapper(a,b):
star = time.process_time()
func(a,b)
end= time.process_time()
print('spend_time:',end-star)
return wrapper
@show_time
def add(a, b):
print(a + b)
add(3,5)
这里可以想到,要是实际情况需要传入很多个参数,我手不得写麻,而且后期还不好维护,所以可以用python带的参数args,kwargs
import time
def show_time(func):
def wrapper(*args, **kwargs):
star = time.process_time()
func(*args,**kwargs)
end= time.process_time()
print('spend_time:',end-star)
return wrapper
@show_time
def add(*args, **kwargs):
sum = 0
for i in args:
sum += i
print(sum)
add(22,13,44,5,6,3,62)
其实就是把传入的参数改成args和kwargs两个可变参数。
这里有一个问题,当加入装饰器之后,函数的name,doc元信息都是消失啦,写的时候就会改变。
如上:
@show_time
def test():
print("cake")
print(test.__name__) # wrapper
def test2():
print('cake2')
print(test2.__nmae__) # test2
所以,python有一个方法functools的wraps,在方法上面加入@wraps(func) ,就可以复用当前的元信息
from functools import wraps
def show_time(func):
@wraps(func)
def wrapper():
func()
return wrapper
@show_time
def test():
print('test_demo')
print(test.__name__)
def test1():
print('test1_demo')
print(test1.__name__)
其中还可以在装饰器中传入参数,flag是True
import time
def cal_time(flag):
def show_time(func):
def wrapper(*args, **kwargs):
star = time.process_time()
func(*args, **kwargs)
end = time.process_time()
if flag == 'True':
print('spend_time:',end-star)
return wrapper
return show_time
@cal_time("True")
def add(*args, **kwargs):
sum = 0
for i in args:
sum += 1
print(sum)
add(1,45,3,2,14)
甚至还有类装饰器,具有高灵活性、高内聚、封装性的特点。
import time
class Foo(object):
def __init__(self, func):
self.func = func
def __call__(self):
star = time.process_time()
self.func()
end = time.process_time()
print('spend_time:', end-star)
@Foo
def bar():
print('test')
bar()
类名Foo可以直接作为装饰器,用call调用。
当然还有内置的装饰器,晚点学习
@a
@b
@c
def f():
相当于 f = a(b(c(f)))
|