本文重點:解決了類里面定義的裝飾器,在同一個類里面使用的問題,并實現了裝飾器的類屬性參數傳遞
目錄:
一、基本裝飾器
二、在類里定義裝飾器,裝飾本類內函數
三、類裝飾器
正文:
一、基本裝飾器
裝飾不帶參數的函數
def clothes(func): def wear(): print('Buy clothes!{}'.format(func.__name__)) return func() return wear @clothes def body(): print('The body feels could!') #備注:@是語法糖 # 不用語法糖的情況下,使用下面語句也能實現裝飾作用:把body再加工,再傳給body # body = clothes(body)
裝飾帶一個參數的函數
def clothes(func): def wear(anything): # 實際是定義一個anything參數,對應body函數參數 print('Buy clothes!{}'.format(func.__name__)) return func(anything) # 執行func函數,并傳入調用傳入的anything參數 # wear = func(anything) # 在這一步,實際上可以看出來,為啥wear必須帶參數,因為它就是func(anything) return wear # 所以clothes的結果是 # clothes = wear = func(anything) # 不用語法糖的情況下就是 # body = clothes(body)('hands') # 進一步證明:print(body.__name__) 顯示的是wear函數 @clothes def body(part): print('The body feels could!{}'.format(part)) body('hands')
裝飾帶不定長參數的函數
通常裝飾器不只裝飾一個函數,每個函數參數的個數也不相同
這個時候使用不定長參數*args,**kwargs
def clothes(func): def wear(*args, **kwargs): print('Buy clothes!{}'.format(func.__name__)) return func(*args, **kwargs) return wear @clothes def body(part): print('The body feels could!{}'.format(part)) @clothes def head(head_wear, num=2): print('The head need buy {} {}!'.format(num, head_wear)) body('hands') head('headdress')
裝飾器帶參數
# 把裝飾器再包裝,實現了seasons傳遞裝飾器參數。 def seasons(season_type): def clothes(func): def wear(*args, **kwargs): if season_type == 1: s = 'spring' elif season_type == 2: s = 'summer' elif season_type == 3: s = 'autumn' elif season_type == 4: s = 'winter' else: print('The args is error!') return func(*args, **kwargs) print('The season is {}!{}'.format(s, func.__name__)) return func(*args, **kwargs) return wear return clothes @seasons(2) def children(): print('i am children') children()
二、在類里定義裝飾器,裝飾本類內函數:
類裝飾器,裝飾函數和類函數調用不同的類函數
把裝飾器寫在類里
在類里面定義個函數,用來裝飾其它函數,嚴格意義上說不屬于類裝飾器。
class Buy(object): def __init__(self, func): self.func = func # 在類里定義一個函數 def clothes(func): # 這里不能用self,因為接收的是body函數 # 其它都和普通的函數裝飾器相同 def ware(*args, **kwargs): print('This is a decrator!') return func(*args, **kwargs) return ware @Buy.clothes def body(hh): print('The body feels could!{}'.format(hh)) body('hh')
裝飾器裝飾同一個類里的函數
背景:想要通過裝飾器修改類里的self屬性值。
class Buy(object): def __init__(self): self.reset = True # 定義一個類屬性,稍后在裝飾器里更改 self.func = True # 在類里定義一個裝飾器 def clothes(func): # func接收body def ware(self, *args, **kwargs): # self,接收body里的self,也就是類實例 print('This is a decrator!') if self.reset == True: # 判斷類屬性 print('Reset is Ture, change Func..') self.func = False # 修改類屬性 else: print('reset is False.') return func(self, *args, **kwargs) return ware @clothes def body(self): print('The body feels could!') b = Buy() # 實例化類 b.body() # 運行body print(b.func) # 查看更改后的self.func值,是False,說明修改完成
三、類裝飾器
定義一個類裝飾器,裝飾函數,默認調用__call__方法
# class Decrator(object): def __init__(self, func): # 傳送的是test方法 self.func = func def __call__(self, *args, **kwargs): # 接受任意參數 print('函數調用CALL') return self.func(*args, **kwargs) # 適應test的任意參數 @Decrator # 如果帶參數,init中的func是此參數。 def test(hh): print('this is the test of the function !',hh) test('hh')
定義一個類裝飾器,裝飾類中的函數,默認調用__get__方法
實際上把類方法變成屬性了,還記得類屬性裝飾器吧,@property
下面自已做一個property
class Decrator(object): def __init__(self, func): self.func = func def __get__(self, instance, owner): ''' instance:代表實例,sum中的self owner:代表類本身,Test類 ''' print('調用的是get函數') return self.func(instance) # instance就是Test類的self class Test(object): def __init__(self): self.result = 0 @Decrator def sum(self): print('There is the Func in the Class !') t = Test() print(t.sum) # 眾所周知,屬性是不加括號的,sum真的變成了屬性
做一個求和屬性sum,統計所有輸入的數字的和
class Decrator(object): def __init__(self, func): self.func = func def __get__(self, instance, owner): print('調用的是get函數') return self.func(instance) class Test(object): def __init__(self, *args, **kwargs): self.value_list = [] if args: for i in args: if str(i).isdigit(): self.value_list.append(i) if kwargs: for v in kwargs.values(): if str(v).isdigit(): self.value_list.append(v) @Decrator def sum(self): result = 0 print(self.value_list) for i in self.value_list: result += i return result t = Test(1,2,3,4,5,6,7,8,i=9,ss=10,strings = 'lll') print(t.sum)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。