溫馨提示×

溫馨提示×

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

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

如何使用Python的裝飾器

發(fā)布時間:2022-03-01 13:38:06 來源:億速云 閱讀:147 作者:小新 欄目:開發(fā)技術

這篇文章將為大家詳細講解有關如何使用Python的裝飾器,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1.定義及使用

例1:裝飾器定義:

      def 裝飾器函數(shù)(外部函數(shù)):
            def 內聯(lián)函數(shù)(*args,**kwargs):
                ...前置裝飾...
                外部函數(shù)(*args,**kwargs)
                ...后置裝飾...
            return 內聯(lián)函數(shù)

 例2:裝飾器兩種調用方式

  •  第一種:裝飾器函數(shù)(外部函數(shù))(參數(shù)1,參數(shù)2......)

  •  第二種:定義時通過 @裝飾器函數(shù)名 綁定 外部函數(shù)(外部函數(shù)調用時觸發(fā))

# coding:utf-8:

if __name__ == '__main__':

    # 例1 裝飾器定義
    # 裝飾器函數(shù) 外部函數(shù)func
    def decorator(func):

        # 內聯(lián)函數(shù) 進行裝飾
        # *args 將 參數(shù)1,參數(shù)2...... 變?yōu)?nbsp;(參數(shù)1,參數(shù)2.......)
        # **kwargs 將 參數(shù)3=參數(shù)值3,參數(shù)4=參數(shù)值4...... 變?yōu)?nbsp;{'參數(shù)3':參數(shù)值3,'參數(shù)4':'參數(shù)值4'......}
        # *args,**kwargs 將 參數(shù)1,參數(shù)2......參數(shù)3=參數(shù)值3,參數(shù)4=參數(shù)值4...... 變?yōu)?nbsp;(參數(shù)1,參數(shù)2.......),{'參數(shù)3':參數(shù)值3,'參數(shù)4':'參數(shù)值4'......}
        def inline(*args, **kwargs):
            # *args,**kwargs 將參數(shù)還原
            # 將 (參數(shù)1,參數(shù)2.......),{'參數(shù)3':參數(shù)值3,'參數(shù)4':'參數(shù)值4'......} 變?yōu)?nbsp;參數(shù)1,參數(shù)2......參數(shù)3=參數(shù)值3,參數(shù)4=參數(shù)值4......
            name = func(*args, **kwargs)
            print(f'name is {name}')

        # return 內聯(lián)函數(shù)
        return inline

    def talk(name):
        return name

    # 例2 裝飾器的兩種調用方式
    # 第一種 裝飾器函數(shù)(外部函數(shù))(參數(shù)1,參數(shù)2......)
    decorator(talk)('xie')  # name is xie

    # 第二種 @裝飾器函數(shù)名 綁定 外部函數(shù)
    @decorator
    def see(name):
        return name
    # 調用時觸發(fā)裝飾器
    see('xie')  # name is xie

2.@classmethod

  •   1.被@classmethod裝飾的類方法可以通過class.方法(參數(shù)1,參數(shù)2......)調用

  •     2.但是定義函數(shù)時 self 需要變成 cls

  •     3.其內部不能調用類的普通方法(無裝飾器修飾的方法),可以調用@classmethod,@staticmethod裝飾的方法

  •     4.能訪問類的屬性 

  •     5.普通類中能通過self調用@classmethod裝飾的方法

# coding:utf-8:

if __name__ == '__main__':


    class A(object):
        __name = 'python'

        # 普通方法
        def talk(self):
            print(self.__name)
            # self.see() 普通類中能通過self調用@classmethod裝飾的方法

        # 被@classmethod裝飾的類方法可以通過class.方法(參數(shù)1,參數(shù)2......)調用
        # 但是定義函數(shù)時 self 需要變成 cls
        @classmethod
        def see(cls, description='good'):
            # cls.talk() Error 不能調用類的普通方法(非@classmethod,@staticmethod修飾的方法)
            # cls.look() 可以調用@classmethod裝飾的方法
            # cls.jump() 可以調用@staticmethod裝飾的方法
            # 能訪問類的屬性
            print(f'{cls .__name} is {description}')

        @classmethod
        def look(cls):
            print(f'I like {cls.__name}')

        @staticmethod
        def jump():
            print(f'I am jump')

    a = A()
    a.talk()  # python
    # A.talk() Error 不能通過class.方法(參數(shù)1,參數(shù)2......)調用
    a.see()  # python is good

    # 通過class.方法(參數(shù)1,參數(shù)2......)調用
    A.see()  # python is good

@staticmethod

  •    1. 被@staticmethod裝飾的類方法可以通過class.方法(參數(shù)1,參數(shù)2......)調用

  •     2. 但是定義函數(shù)時 無須self和cls

  •     3. 由于其無self,cls注定其無法訪問類屬性&調用類方法

  •     4. 在類的普通方法中可以通過self調用@staticmethod裝飾的方法

# coding:utf-8:

if __name__ == '__main__':
    '''
      '''

    class B(object):
        __name = 'php'

        def talk(self):
            # 可以通過self調用@staticmethod裝飾的方法
            self.see(self.__name)

        # 無須self,cls
        @staticmethod
        def see(description='good'):
            print(f'description is {description}')


    B.see()  # description is good
    B.see('ok')  # description is ok
    B().talk()  # description is php

@property

  • 1.@property裝飾的函數(shù)被用來代替類中與函數(shù)名相同的屬性

      定義: @property
            def 屬性名(self):
                .......

  •   2.被@property裝飾器代替的屬性,無法通過object.屬性名=屬性值進行賦值(除非使用了@屬性名.setter裝飾器):

      定義: @屬性名.setter
            def 屬性名(self,屬性值):
                ......  

  • 3.被@property修飾的函數(shù)不能在外部通過object.函數(shù)名()調用,只能object.函數(shù)名 當做屬性

  • 4.只有被@property代替了的屬性才能使用@屬性名.setter 裝飾器

  • 5. __setattr__ 的優(yōu)先級高于 @屬性名.setter裝飾器的優(yōu)先級

# coding:utf-8:

if __name__ == '__main__':
    '''
   
    '''
    class A(object):
        __name = 'python'
        sex = 'man'

        # 不能設置成私有
        # @property裝飾的函數(shù)被用來代替類中與函數(shù)名相同的屬性
        # 這個代替了name屬性
        @property
        def name(self):
            return self.__name

@property

def sex(self):
            return 'woman'

        # 解決被替代屬性的 object.屬性=屬性值 賦值問題
        # 配合@property裝飾器使用,只有被@property代替了的屬性才能使用@屬性名.setter 裝飾器
        @name.setter
        def name(self, value):
            print(f'value is {value}')

        # __setattr__ 的優(yōu)先級高于 @屬性名.setter裝飾器的優(yōu)先級
        # def __setattr__(self, key, value):
        #     print(f'key is {key}, value is {value}')


    a = A()
    print(a.name)  # python
    # print(a.name()) Error 被@property修飾的函數(shù)不能在外部通過object.函數(shù)名()調用,只能object.函數(shù)名 當做屬性

    # 被@property代替了
    print(a.sex)  # 是 woman 不是 man

    # a.sex = 'man' Error 被代替的屬性,不能通過object.屬性名 = 屬性值 進行賦值,除非有@屬性名.setter裝飾
    a.name = 'python3.7'  # value is python3.7

關于“如何使用Python的裝飾器”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

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

AI