Python裝飾器
- 裝飾器的功能和實現方法
- 功能:對函數和類功能進行擴展
- 裝飾模式有不少經典的使用場景,例如插入日誌、性能測試、事務處理等等,有了裝飾器,就能夠提取大量函數中與自己功能無關的相似代碼,從而達到代碼重用的目的。
- 實現:裝飾器能夠是函數,也能夠是一個對象,總之是能夠將要裝飾的函數做爲參數傳入並返回函數或對象再賦值給函數或類
- 裝飾器語法糖:在Python中,可使用」@」語法糖來精簡裝飾器的代碼
- 下面使用不一樣的方式實現裝飾器來講明:
def decorator(func):
print(func)
def inner():
print('執行demo函數以前增長一些功能')
func()
print('執行demo函數以後增長一些功能')
return inner
@decorator
def demo():
print('測試裝飾器的函數')
return 0
demo()
複製代碼
<function demo at 0x000001D3146CE158>
執行demo函數以前增長一些功能
測試裝飾器的函數
執行demo函數以後增長一些功能
複製代碼
def decorator(func):
print(func)
def inner(var):
print('執行demo函數以前增長一些功能')
res = func(var)
print('執行demo函數以後增長一些功能')
return res
return inner
@decorator
def demo(var):
print('測試裝飾器的函數')
return var
test = demo('測試')
print(test)
複製代碼
<function demo at 0x000001D3146EE048>
執行demo函數以前增長一些功能
測試裝飾器的函數
執行demo函數以後增長一些功能
測試
複製代碼
def outer(arg):
def decorator(func):
print(func)
def inner1(var):
print('執行demo函數以前增長一些功能1')
res = func(var)
print('執行demo函數以後增長一些功能1')
return res
def inner2(var):
print('執行demo函數以前增長一些功能2')
res = func(var)
print('執行demo函數以後增長一些功能2')
return res
if arg == 1 :
return inner1
elif arg == 2 :
return inner2
return decorator
@outer(1)
def demo(var):
print('測試裝飾器的函數')
return var
test = demo('測試')
print(test)
print('\n###############################################\n')
@outer(2)
def demo(var):
print('測試裝飾器的函數')
return var
test = demo('測試')
print(test)
複製代碼
<function demo at 0x000001D3146CE840>
執行demo函數以前增長一些功能1
測試裝飾器的函數
執行demo函數以後增長一些功能1
測試
###############################################
<function demo at 0x000001D314702B70>
執行demo函數以前增長一些功能2
測試裝飾器的函數
執行demo函數以後增長一些功能2
測試
複製代碼
class decorator:
def __init__(self,arg):
self.arg = arg
def __call__(self,func):
self.func = func
return self.inner
def inner(self,var):
print('執行demo函數以前增長一些功能2')
res = self.func(var)
print('執行demo函數以後增長一些功能2')
return res
@decorator(1)
def demo(var):
print(var)
return var
res = demo('123')
print(res)
複製代碼
執行demo函數以前增長一些功能2
123
執行demo函數以後增長一些功能2
123
複製代碼
objs = {}
def decorator(cls):
def inner():
obj = None
if cls in objs:
return objs[cls]
else :
obj = object.__new__(cls)
objs[cls] = obj
return obj
return inner
@decorator
class demo1:
pass
@decorator
class demo2:
pass
t1 = demo1()
t2 = demo1()
print(id(t1),id(t2))
t21 = demo2()
t22 = demo2()
print(id(t21),id(t22))
複製代碼
2006092685552 2006092685552
2006092688128 2006092688128
複製代碼
def decorator1(func):
def inner():
print('裝飾器1')
func()
print('裝飾器1')
return inner
def decorator2(func):
def inner():
print('裝飾器2')
func()
print('裝飾器2')
return inner
@decorator2
@decorator1
def demo():
print('demo函數')
demo()
複製代碼
裝飾器2
裝飾器1
demo函數
裝飾器1
裝飾器2
複製代碼
總結
- 裝飾器本質上是一個python函數,它可讓其餘函數在不作任何代碼變更的前提下增長額外的功能,裝飾器的返回值也是一個函數對象
- python內置的三個裝飾器:staticmethod,classmethod和property
- staticmethod:把類中的方法定義爲靜態方法,使用staticmethod裝飾的方法可使用類或者類的實例對象來調用,不須要傳入self
- classmethod:把類中的方法定義爲類方法,使用classmethod裝飾的方法可使用類或者類的實例對象來調用,並將該class對象隱式的做爲第一個參數傳入
- property:把方法變成屬性
- 三種內置裝飾器之後再詳述