在学习的时候发现直接调用装饰器可以很方便接入查询时间的函数
- 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)))