最近在跟着学廖雪峰老师的教程。在项目实例阶段,直接上来就是decorator()的写法,很是摸不到头脑,所以在csdn博客圈里补下这块的知识。
原来decorator是为了少写代码啊! 做几个试验
>>> def do_something():
for i in range(1000):
pass
print('test')
>>> do_something()
test
现在输出功能函数的执行时间,首先使用函数嵌套调用的方式(不是装饰器写法),定义一个performance函数,以函数为入参,输出runtime,作为fun函数的性能情况
>>> import time
>>> def performance(fun):
start = time.time()
fun()
runtime = time.time() - start
print(runtime)
>>> def do_something():
for i in range(1000):
pass
print('test')
>>> performance(do_something)test0.03552699089050293>>>
用decorator的方式改写上述写法,采用python的@写法,在do_something()函数调用前,使用performance装饰器
>>> import time
>>> def performance(fun):
start = time.time()
fun()
runtime = time.time() - start
print(runtime)
>>> @performance
def do_something():
for i in range(10000):
pass
print('test')
test
0.08151555061340332
>>> 带单参函数的装饰器
假设对do_something()函数做改造,允许传入一个参数,再次改写装饰器
>>> import time
>>> def performance(fun):
def wrapper(name):
start = time.time()
fun(name)
runtime = time.time() - start
print(runtime)
return wrapper
>>> @performance
def do_something(name):
for i in range(10000):
pass
print("test",name)
>>> do_something('haha')
test haha
0.055966854095458984
>>>
再次对do_something函数做改造,允许传入多个参数,在此情况下,对装饰器做改写
>>> import time
>>> def performance(fun):
def wrapper(*args, **kw):
start = time.time()
fun(*args, **kw)
runtime = time.time() - start
print(runtime)
return wrapper
>>> @performance
def do_something(name):
for i in range(1000):
pass
print('test',name)
>>> @performance
def do_something2(name, user):
for i in range(1000):
pass
print(user,' test ',name)
>>> do_something('Jack')
test Jack
0.06430554389953613
>>> do_something2('haha','chen')
chen test haha
0.11893939971923828
>>>
再次改造装饰器,装饰器有入参调用次数,默认为1
>>> import time
>>> def performance(runtimes=1):
def _performance(run):
def wrapper(*args, **kw):
start = time.time()
for i in range(runtimes):
run(*args, **kw)
runtime = time.time() - start
print(runtime)
return wrapper
return _performance
>>> @performance(2)
def do_something(*args, **kw):
for i in range(10000):
pass
print(args)
>>> do_something('chen','it works')
('chen', 'it works')
('chen', 'it works')
0.053436994552612305
>>>
装饰器写法,是为了减少代码量,尽量做到代码复用。引用官方手册的说明,装饰器写法(写法二),等同于写法一。
def f(...): ...
#写法一: f = staticmethod(f) #写法二: @staticmethod def f(...): ...