前面一篇对python装饰器有了初步的了解了,可是还不够完美,领导看了后又提出了新的需求,但愿运行的日志能显示出具体运行的哪一个函数。python
__name__
用于获取函数的名称,__doc__
用于获取函数的docstring内容(函数的注释)app
import time def func_a(a): '''func_a --> hello''' print("hello"+a) time.sleep(0.5) return True def func_b(b, c="xx"): '''func_b --> world''' print("world"+b+c) time.sleep(0.8) return True if __name__ == '__main__': print(func_a.__name__) # 结果 func_a print(func_a.__doc__) # func_a --> hello print(func_b.__name__) # func_b print(func_b.__doc__) # func_b --> world
在装饰器里面添加2行代码,打印正在运行函数的名称和docstring内容函数
import time def runtime(func): '''runtime decorators''' def wrapper(*args, **kwargs): '''wrapper inner fuction''' print("running function : %s" % func.__name__) print("docstring: %s" % func.__doc__) start = time.time() f = func(*args, **kwargs) # 原函数 end = time.time() print("运行时长:%.4f 秒" % (end-start)) return f return wrapper @runtime def func_a(a): '''func_a --> hello''' print("hello"+a) time.sleep(0.5) return True @runtime def func_b(b, c="xx"): '''func_b --> world''' print("world"+b+c) time.sleep(0.8) return True if __name__ == '__main__': func_a("a") print(func_a.__name__) print(func_a.__doc__)
运行结果日志
running function : func_a docstring: func_a --> hello helloa 运行时长:0.5008 秒 wrapper wrapper inner fuction
从运行的结果能够看出,func_a.__name__
运行的结果是wrapper,func_a.__doc__
运行的结果是wrapper inner fuction。
也就是说被装饰后的函数其实已是另一个函数了(函数名等函数属性会发生改变),那这个问题如何解决呢?
这就须要用到functools里面的一个wraps函数了code
当func_a函数被装饰后,致使了一个反作用:自身的函数属性和docstring内容变成了wrapper函数的属性了。
这里需用到functools里面的一个wraps的装饰器来消除这样的反作用。string
import time from functools import wraps def runtime(func): '''runtime decorators''' @wraps(func) def wrapper(*args, **kwargs): '''wrapper inner fuction''' print("running function : %s" % func.__name__) print("docstring: %s" % func.__doc__) start = time.time() f = func(*args, **kwargs) # 原函数 end = time.time() print("运行时长:%.4f 秒" % (end-start)) return f return wrapper
只需在wrapper函数上加上@wraps(func)
便可解决it
运行结果自动化
running function : func_a docstring: func_a --> hello helloa 运行时长:0.5004 秒 func_a func_a --> hello
带参数的装饰器,能够写成类装饰器io
import time from functools import wraps class runtime(object): '''runtime class decorators''' def __init__(self, slowly=1): self.slowly = slowly def __call__(self, func): @wraps(func) def wrapper(*args, **kwargs): '''wrapper inner fuction''' print("running function : %s" % func.__name__) print("docstring: %s" % func.__doc__) start = time.time() f = func(*args, **kwargs) # 原函数 end = time.time() t = end-start time.sleep((self.slowly-1)*t) # 延迟效果 new_end = time.time() print("运行时长:%.4f 秒" % (new_end-start)) return f return wrapper @runtime(1.5) def func_a(a): '''func_a --> hello''' print("hello"+a) time.sleep(0.5) return True @runtime() def func_b(b, c="xx"): '''func_b --> world''' print("world"+b+c) time.sleep(0.8) return True if __name__ == '__main__': func_a("a") print(func_a.__name__) print(func_a.__doc__)
运行结果function
running function : func_a docstring: func_a --> hello helloa 运行时长:0.7522 秒 func_a func_a --> hello
python自动化交流 QQ群:779429633