-
?為什么要使用裝飾器
- 在軟件開發(fā)的過程中,我們發(fā)現(xiàn)經(jīng)常用到重復(fù)的代碼,這就大大的增加了開發(fā)的周期,為了使得開發(fā)更為高效,python中主要特性之一就是裝飾器。(
修改/生成/包裝經(jīng)常使用的代碼
)
- 在軟件開發(fā)的過程中,我們發(fā)現(xiàn)經(jīng)常用到重復(fù)的代碼,這就大大的增加了開發(fā)的周期,為了使得開發(fā)更為高效,python中主要特性之一就是裝飾器。(
-
?如何自己編寫一個(gè)裝飾器函數(shù)
- 有時(shí)候,我們會遇到這樣的問題,事先已經(jīng)寫好某些函數(shù),但是想要在這些函數(shù)的基礎(chǔ)上添加一些額外的功能(
登錄驗(yàn)證/記錄日志/生成時(shí)間戳
) - 定義一個(gè)裝飾器函數(shù):
- 有時(shí)候,我們會遇到這樣的問題,事先已經(jīng)寫好某些函數(shù),但是想要在這些函數(shù)的基礎(chǔ)上添加一些額外的功能(
>>> import time
>>> from functools import wraps
>>>
>>>
>>> def timeabout(func):
'''定義一個(gè)裝飾器用來生成執(zhí)行某函數(shù)需要的時(shí)間戳'''
@wraps(func)
def wrapper(self, *args, **kwargs):
s = time.time() #開始時(shí)間
result = func(self, *args, **kwargs) #func指的未被裝飾的原始函數(shù)
e = time.time() #結(jié)束時(shí)間
print(func.__name__,e - s) #打印兩部分內(nèi)容(被裝飾的函數(shù)名,需要的時(shí)間戳)
return result
return wrapper
- 使用此裝飾器
>>>@timeabout #使用此裝飾器對下列階乘函數(shù)進(jìn)行包裝處理
def factorial(n):
if n == 1:
return 1
else:
return factorial(n-1)*n
>>>
>>> factorial(10)
factorial 0.0
factorial 0.05403733253479004 #經(jīng)過裝飾器處理的階乘函數(shù)
factorial 0.06404519081115723
factorial 0.07304859161376953
factorial 0.08205389976501465
factorial 0.0930624008178711
factorial 0.10106801986694336
factorial 0.10907340049743652
factorial 0.11607766151428223
factorial 0.12308287620544434
3628800 #階乘函數(shù)的結(jié)果
>>>
- 裝飾器即函數(shù),可以接受函數(shù)作為輸入,并且返回一個(gè)新的函數(shù)作為輸出。
#方法一和方法二執(zhí)行后效果一樣
#方法一
@timeabout
def factorial(n):
if n == 1:
return 1
else:
return factorial(n-1)*n
#方法二
```python
def factorial(n):
if n == 1:
return 1
else:
return factorial(n-1)*n
factorial = timeabout(factorial)
- 裝飾器內(nèi)部創(chuàng)建了一個(gè)新的函數(shù)(如
wrapper
),*args, **kwargs
用來接收任何形式的輸入?yún)?shù)。如需了解python中的函數(shù)如何使用,請瀏覽本作者關(guān)于函數(shù)的文章。
- 在此函數(shù)
wrapper
內(nèi)部,需要調(diào)用原來的函數(shù)(需要裝飾的函數(shù)
),將其作為參數(shù)輸入,并返回結(jié)果。 - 可以添加額外的代碼,實(shí)現(xiàn)其它的方法。
- 新的函數(shù)(如
wrapper
)會作為此裝飾器的結(jié)果返回,取代原來的函數(shù)。