前面一篇對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