Python的裝飾器詳情介紹
1.定義及使用
例1:裝飾器定義:
def 裝飾器函數(外部函數):
def 內聯函數(*args,**kwargs):
...前置裝飾...
外部函數(*args,**kwargs)
...后置裝飾...
return 內聯函數
例2:裝飾器兩種調用方式
- 第一種:裝飾器函數(外部函數)(參數1,參數2......)
- 第二種:定義時通過 @裝飾器函數名 綁定 外部函數(外部函數調用時觸發(fā))
# coding:utf-8:
if __name__ == '__main__':
? ? # 例1 裝飾器定義
? ? # 裝飾器函數 外部函數func
? ? def decorator(func):
? ? ? ? # 內聯函數 進行裝飾
? ? ? ? # *args 將 參數1,參數2...... 變?yōu)?(參數1,參數2.......)
? ? ? ? # **kwargs 將 參數3=參數值3,參數4=參數值4...... 變?yōu)?{'參數3':參數值3,'參數4':'參數值4'......}
? ? ? ? # *args,**kwargs 將 參數1,參數2......參數3=參數值3,參數4=參數值4...... 變?yōu)?(參數1,參數2.......),{'參數3':參數值3,'參數4':'參數值4'......}
? ? ? ? def inline(*args, **kwargs):
? ? ? ? ? ? # *args,**kwargs 將參數還原
? ? ? ? ? ? # 將 (參數1,參數2.......),{'參數3':參數值3,'參數4':'參數值4'......} 變?yōu)?參數1,參數2......參數3=參數值3,參數4=參數值4......
? ? ? ? ? ? name = func(*args, **kwargs)
? ? ? ? ? ? print(f'name is {name}')
? ? ? ? # return 內聯函數
? ? ? ? return inline
? ? def talk(name):
? ? ? ? return name
? ? # 例2 裝飾器的兩種調用方式
? ? # 第一種 裝飾器函數(外部函數)(參數1,參數2......)
? ? decorator(talk)('xie') ?# name is xie
? ? # 第二種 @裝飾器函數名 綁定 外部函數
? ? @decorator
? ? def see(name):
? ? ? ? return name
? ? # 調用時觸發(fā)裝飾器
? ? see('xie') ?# name is xie2.@classmethod
- 1.被
@classmethod裝飾的類方法可以通過class.方法(參數1,參數2......)調用 - 2.但是定義函數時 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.方法(參數1,參數2......)調用
? ? ? ? # 但是定義函數時 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.方法(參數1,參數2......)調用
? ? a.see() ?# python is good
? ? # 通過class.方法(參數1,參數2......)調用
? ? A.see() ?# python is good@staticmethod
- 1. 被@staticmethod裝飾的類方法可以通過class.方法(參數1,參數2......)調用
- 2. 但是定義函數時 無須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裝飾的函數被用來代替類中與函數名相同的屬性
定義: @property
def 屬性名(self):
.......
- 2.被@property裝飾器代替的屬性,無法通過object.屬性名=屬性值進行賦值(除非使用了@屬性名.setter裝飾器):
定義: @屬性名.setter
def 屬性名(self,屬性值):
......
- 3.被@property修飾的函數不能在外部通過object.函數名()調用,只能object.函數名 當做屬性
- 4.只有被@property代替了的屬性才能使用@屬性名.setter 裝飾器
- 5. __setattr__ 的優(yōu)先級高于 @屬性名.setter裝飾器的優(yōu)先級
# coding:utf-8: if __name__ == '__main__': ? ? ''' ? ? ? ? ''' ? ? class A(object): ? ? ? ? __name = 'python' ? ? ? ? sex = 'man' ? ? ? ? # 不能設置成私有 ? ? ? ? # @property裝飾的函數被用來代替類中與函數名相同的屬性 ? ? ? ? # 這個代替了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修飾的函數不能在外部通過object.函數名()調用,只能object.函數名 當做屬性
? ? # 被@property代替了
? ? print(a.sex) ?# 是 woman 不是 man
? ? # a.sex = 'man' Error 被代替的屬性,不能通過object.屬性名 = 屬性值 進行賦值,除非有@屬性名.setter裝飾
? ? a.name = 'python3.7' ?# value is python3.7
到此這篇關于Python的裝飾器詳情介紹的文章就介紹到這了,更多相關Python裝飾器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
如何在python中使用openpyxl庫讀寫Excel.xlsx文件(有參考列程)
這篇文章主要給大家介紹了關于如何在python中使用openpyxl庫讀寫Excel.xlsx文件的相關資料,openpyxl是一個第三方庫,可以處理xlsx格式的Excel文件,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-06-06
Python與xlwings黃金組合處理Excel各種數據和自動化任務
這篇文章主要為大家介紹了Python與xlwings黃金組合處理Excel各種數據和自動化任務示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪<BR>2023-12-12

