溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python裝飾器高級版—Python類內定義裝飾器并傳遞self參數

發布時間:2020-07-14 22:18:09 來源:網絡 閱讀:3326 作者:等你的破船 欄目:編程語言

本文重點:解決了類里面定義的裝飾器,在同一個類里面使用的問題,并實現了裝飾器的類屬性參數傳遞


目錄:

一、基本裝飾器

二、在類里定義裝飾器,裝飾本類內函數

三、類裝飾器



正文:

一、基本裝飾器

        裝飾不帶參數的函數

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)

    



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女