本文重點:解決了類里面定義的裝飾器,在同一個類里面使用的問題,并實現了裝飾器的類屬性參數傳遞
目錄:
一、基本裝飾器
二、在類里定義裝飾器,裝飾本類內函數
三、類裝飾器
正文:
一、基本裝飾器
裝飾不帶參數的函數
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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。