函数装饰器
2020-05-11 本文已影响0人
蝉时雨丶
不带参数的装饰器
>>> import time
>>> def timer(func):
def deco():
start=time.time()
func()
stop=time.time()
print(stop-start)
return deco
>>> def test():
time.sleep(2)
print("test is running!")
>>> test=timer(test)
>>> test()
test is running!
2.002716302871704
等价于
>>> import time
>>> def timer(func):
def deco():
start=time.time()
func()
stop=time.time()
print(stop-start)
return deco
>>> @timer
def test():
time.sleep(2)
print("test is running!")
>>> test()
test is running!
2.025238513946533
对带参数函数进行装饰
def w_say(fun):
"""
如果原函数有参数,那闭包函数必须保持参数个数一致,并且将参数传递给原方法
"""
def inner(name):
"""
如果被装饰的函数有行参,那么闭包函数必须有参数
:param name:
:return:
"""
print('say inner called')
fun(name)
return inner
@w_say
def hello(name):
print('hello ' + name)
hello('wangcai')
输出结果为
say inner called
hello wangcai
具体说明代码注释已经有了,就不再单独说明了。
此时,也许你就会问了,那是一个参数的,如果多个或者不定长参数呢,该如何处理呢?看看下面的代码你就秒懂了。
def w_add(func):
def inner(*args, **kwargs):
print('add inner called')
func(*args, **kwargs)
return inner
@w_add
def add(a, b):
print('%d + %d = %d' % (a, b, a + b))
@w_add
def add2(a, b, c):
print('%d + %d + %d = %d' % (a, b, c, a + b + c))
add(2, 4)
add2(2, 4, 6)
输出结果为:
add inner called
2 + 4 = 6
add inner called
2 + 4 + 6 = 12
对带有返回值的函数进行装饰
下面对有返回值的函数进行装饰,按照之前的写法,代码是这样的
def w_test(func):
def inner():
print('w_test inner called start')
func()
print('w_test inner called end')
return inner
@w_test
def test():
print('this is test fun')
return 'hello'
ret = test()
print('ret value is %s' % ret)
输出结果为:
w_test inner called start
this is test fun
w_test inner called end
ret value is None
可以发现,此时,并没有输出test函数的‘hello’,而是None,那是为什么呢,可以发现,在inner函数中对test进行了调用,但是没有接受不了返回值,也没有进行返回,那么默认就是None了,知道了原因,那么来修改一下代码:
def w_test(func):
def inner():
print('w_test inner called start')
str = func()
print('w_test inner called end')
return str
return inner
@w_test
def test():
print('this is test fun')
return 'hello'
ret = test()
print('ret value is %s' % ret)
输出结果:
w_test inner called start
this is test fun
w_test inner called end
ret value is hello
带参数的装饰器
def func_args(pre='xiaoqiang'):
def w_test_log(func):
def inner():
print('...记录日志...visitor is %s' % pre)
func()
return inner
return w_test_log
# 带有参数的装饰器能够起到在运行时,有不同的功能
# 先执行func_args('wangcai'),返回w_test_log函数的引用
# @w_test_log
# 使用@w_test_log对test_log进行装饰
@func_args('wangcai')
def test_log():
print('this is test log')
test_log()
输出结果为:
...记录日志...visitor is wangcai
this is test log
简单理解,带参数的装饰器就是在原闭包的基础上又加了一层闭包,通过外层函数func_args的返回值w_test_log就看出来了,具体执行流程在注释里已经说明了。
好处就是可以在运行时,针对不同的参数做不同的应用功能处理。