當需要對已定義的函數進行功能擴展但又不能去改變原有函數時就會用到裝飾器。裝飾器在python中是非常常用且重要的功能,是一種python的語法糖。
在理解裝飾器之前先看下面的加法函數:
def add(x,y):
return x + y
若想增加信息輸出功能:
def add(x,y):
prtint("output")
return x + y
這樣修改耦合太高,並且侵入了原有的業務代碼。我們可以改成這樣:
def add(x,y):
return x + y
def test(fn):
print('begin') # 增強的輸出
print('end') # 增強的功能
return fn
print(test(add)(4,5))
使函數test()更便捷的傳參:
def add(x,y):
return x + y
def test(fn,*args,**kwargs): #相當於是*args,**kwargs作爲參數傳給fn這一函數對象。
print('begin') # 增強的輸出
print('end') # 增強的功能
return fn(*args,**kwargs) #
print(test(add,4,23))
對test()函數進行柯里化,讓它只接收函數對象:
def test(fn):
def wrapper(*args,**kwargs):
print("hello")
print("world")
return fn(*args,**kwargs)
return wrapper
print(test(add)(3,6))
使用裝飾器:
def test(fn):
def wrapper(*args,**kwargs):
print("hello")
print("world")
return fn(*args,**kwargs)
return wrapper
@test #等價於add = test(add)
def add(x,y):
return x + y
@test #用test()函數再對add1()函數進行一次裝飾,等價於add1 = test(add1)
def add1(x,y,z):
return x + y + z
print(add(x=4,y=6))
print(add1(3,5,43))
可以理解爲裝飾器是用一個函數將另一個函數裝飾了一次,在這裏看似調用的是add()和add1()函數,但實際上調用的是test()函數,再由test()函數返回wrapper函數對象將參數傳給內部fn()函數,test()函數中的參數是什麼,fn()函數就是什麼。(裝飾器的用@表示。)