背景
裝飾器模式是我經常使用的一種Python設計模式,也非常的好用,一般是用函數實現,但是這種實現有一個缺點。
如果邏輯非常的複雜,寫在一個函數中,會讓函數非常長且冗餘,需要把小功能的抽象,然後再進行組合 而類裝飾器,就適用於這種場景。
# coding=utf-8
# 深入理解類裝飾器
# 一:類裝飾器(都不帶參數)
class ClsDeco:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f'Running {self.func.__name__}')
self.func()
print('End')
@ClsDeco # 等價於 bar = ClsDeco(bar)
def bar():
print('do something')
# call bar()
# OUT:
# Running bar
# do something
# End
# 二:類裝飾器帶參數
class ClsDeco1:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self, func, *args, **kwargs):
print(f'Running {func.__name__}')
print(f'Using x + y = {self.x + self.y}')
return func
@ClsDeco1(1,2) # 等價於 bar1 = ClsDeco1(1,2)(bar1)
def bar1():
print('do something')
# call bar1()
# OUT:
# Running bar1
# Using x + y = 3
# do something
# 三:類裝飾器不帶參數,被包裝對象帶參數
class ClsDeco2:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f'Running {self.func.__name__}')
self.func(*args, **kwargs)
print('End')
@ClsDeco2 # 等價於bar2 = ClsDeco2(bar2)
def bar2(a,b):
print('do something')
print(f'return a + b = {a + b}')
# bar2(1,2)
# OUT:
# Running bar2
# do something
# return a + b = 3
# End
# 四:類裝飾器帶參數且被裝飾對象也帶參數
class ClsDeco3:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self, func, *args, **kwargs):
print(f'Using x + y = {self.x + self.y}')
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print('Ending')
return wrapper
@ClsDeco3(1, 2) # 等價於 bar3 = ClsDeco3(1, 2)(bar3)
def bar3(a, b):
print('do something')
print(f'return a + b = {a + b}')
# call bar3(1,2)
# OUT:
# Using x + y = 3
# do something
# return a + b = 3
# Ending
if __name__ == '__main__':
bar3(1,2)