Python的裝飾器詳情介紹
1.定義及使用
例1:裝飾器定義:
def 裝飾器函數(shù)(外部函數(shù)):
def 內(nèi)聯(lián)函數(shù)(*args,**kwargs):
...前置裝飾...
外部函數(shù)(*args,**kwargs)
...后置裝飾...
return 內(nèi)聯(lián)函數(shù)
例2:裝飾器兩種調(diào)用方式
- 第一種:裝飾器函數(shù)(外部函數(shù))(參數(shù)1,參數(shù)2......)
- 第二種:定義時通過 @裝飾器函數(shù)名 綁定 外部函數(shù)(外部函數(shù)調(diào)用時觸發(fā))
# coding:utf-8: if __name__ == '__main__': ? ? # 例1 裝飾器定義 ? ? # 裝飾器函數(shù) 外部函數(shù)func ? ? def decorator(func): ? ? ? ? # 內(nèi)聯(lián)函數(shù) 進行裝飾 ? ? ? ? # *args 將 參數(shù)1,參數(shù)2...... 變?yōu)?(參數(shù)1,參數(shù)2.......) ? ? ? ? # **kwargs 將 參數(shù)3=參數(shù)值3,參數(shù)4=參數(shù)值4...... 變?yōu)?{'參數(shù)3':參數(shù)值3,'參數(shù)4':'參數(shù)值4'......} ? ? ? ? # *args,**kwargs 將 參數(shù)1,參數(shù)2......參數(shù)3=參數(shù)值3,參數(shù)4=參數(shù)值4...... 變?yōu)?(參數(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)?參數(shù)1,參數(shù)2......參數(shù)3=參數(shù)值3,參數(shù)4=參數(shù)值4...... ? ? ? ? ? ? name = func(*args, **kwargs) ? ? ? ? ? ? print(f'name is {name}') ? ? ? ? # return 內(nèi)聯(lián)函數(shù) ? ? ? ? return inline ? ? def talk(name): ? ? ? ? return name ? ? # 例2 裝飾器的兩種調(diào)用方式 ? ? # 第一種 裝飾器函數(shù)(外部函數(shù))(參數(shù)1,參數(shù)2......) ? ? decorator(talk)('xie') ?# name is xie ? ? # 第二種 @裝飾器函數(shù)名 綁定 外部函數(shù) ? ? @decorator ? ? def see(name): ? ? ? ? return name ? ? # 調(diào)用時觸發(fā)裝飾器 ? ? see('xie') ?# name is xie
2.@classmethod
- 1.被
@classmethod
裝飾的類方法可以通過class.方法(參數(shù)1,參數(shù)2......)調(diào)用 - 2.但是定義函數(shù)時 self 需要變成 cls
- 3.其內(nèi)部不能調(diào)用類的普通方法(無裝飾器修飾的方法),可以調(diào)用
@classmethod
,@staticmethod
裝飾的方法 - 4.能訪問類的屬性
- 5.普通類中能通過self調(diào)用@classmethod裝飾的方法
# coding:utf-8: if __name__ == '__main__': ? ? class A(object): ? ? ? ? __name = 'python' ? ? ? ? # 普通方法 ? ? ? ? def talk(self): ? ? ? ? ? ? print(self.__name) ? ? ? ? ? ? # self.see() 普通類中能通過self調(diào)用@classmethod裝飾的方法 ? ? ? ? # 被@classmethod裝飾的類方法可以通過class.方法(參數(shù)1,參數(shù)2......)調(diào)用 ? ? ? ? # 但是定義函數(shù)時 self 需要變成 cls ? ? ? ? @classmethod ? ? ? ? def see(cls, description='good'): ? ? ? ? ? ? # cls.talk() Error 不能調(diào)用類的普通方法(非@classmethod,@staticmethod修飾的方法) ? ? ? ? ? ? # cls.look() 可以調(diào)用@classmethod裝飾的方法 ? ? ? ? ? ? # cls.jump() 可以調(diào)用@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......)調(diào)用 ? ? a.see() ?# python is good ? ? # 通過class.方法(參數(shù)1,參數(shù)2......)調(diào)用 ? ? A.see() ?# python is good
@staticmethod
- 1. 被@staticmethod裝飾的類方法可以通過class.方法(參數(shù)1,參數(shù)2......)調(diào)用
- 2. 但是定義函數(shù)時 無須self和cls
- 3. 由于其無self,cls注定其無法訪問類屬性&調(diào)用類方法
- 4. 在類的普通方法中可以通過self調(diào)用@staticmethod裝飾的方法
# coding:utf-8: if __name__ == '__main__': ? ? ''' ? ? ? ''' ? ? class B(object): ? ? ? ? __name = 'php' ? ? ? ? def talk(self): ? ? ? ? ? ? # 可以通過self調(diào)用@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ù)名()調(diào)用,只能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ù)名()調(diào)用,只能object.函數(shù)名 當做屬性 ? ? # 被@property代替了 ? ? print(a.sex) ?# 是 woman 不是 man ? ? # a.sex = 'man' Error 被代替的屬性,不能通過object.屬性名 = 屬性值 進行賦值,除非有@屬性名.setter裝飾 ? ? a.name = 'python3.7' ?# value is python3.7
到此這篇關(guān)于Python的裝飾器詳情介紹的文章就介紹到這了,更多相關(guān)Python裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python合并已經(jīng)存在的sheet數(shù)據(jù)到新sheet的方法
今天小編就為大家分享一篇python合并已經(jīng)存在的sheet數(shù)據(jù)到新sheet的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12python opencv圓、橢圓與任意多邊形的繪制實例詳解
在本篇文章里小編給大家整理的是關(guān)于python-opencv-圓、橢圓與任意多邊形的繪制內(nèi)容,需要的朋友們可以學習參考下。2020-02-02python multiprocessing多進程變量共享與加鎖的實現(xiàn)
這篇文章主要介紹了python multiprocessing多進程變量共享與加鎖的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10利用pandas如何實現(xiàn)類似sql中的left join操作
這篇文章主要介紹了利用pandas如何實現(xiàn)類似sql中的left join操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06python opencv實現(xiàn)gif圖片分解的示例代碼
這篇文章主要介紹了python opencv實現(xiàn)gif圖片分解的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12keras 回調(diào)函數(shù)Callbacks 斷點ModelCheckpoint教程
這篇文章主要介紹了keras 回調(diào)函數(shù)Callbacks 斷點ModelCheckpoint教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06