回顧
一個完整的閉包函式要滿足那些條件
1,函式里面套函式
2,外層函式回傳的事內層函式的函式名
3,內層函式有對外部非全域變數的參考
多個裝飾器并存
多個裝飾器裝飾同一個類,方法的時候,裝飾器的加載和執行是什么樣子的呢?
1 @login_check 2 @timer 3 def func(): 4 print("被裝飾的函式")
多個裝飾器裝飾同一個方法的時候,按照從下往上裝飾的順序
運行的時候從上往下執行,
即 從下往上裝飾,從上向下執行,
python的內置裝飾器三大件兒
classmethod
@classmethod 被該裝飾器裝飾之后該方法就是一個類方法
被裝飾之后方法就不能在寫self的形參了,因為self代表實體本身,而變成類方法之后不能用self來代表類本身,
需要用cls來代替self,cls代表類本身,self代表實體本身,
類方法可以直接通過類呼叫,無需實體化
staticmethod
靜態方法 靜態方法默認是沒有引數的,
加上之后就是一個靜態方法,表示不經過實體化即可使用,類和實體均可呼叫
prperty
設定只讀屬性,裝飾之后只可讀兒不能修改,后面進行訪問的時候也只能讀取,
呼叫的時候可以直接像呼叫屬性一樣呼叫,
注意: 不可以通過類來呼叫,需要通過實體進行呼叫,
1 @property # 設定只讀屬性 2 def read_attr(self): # 只可讀不能進行更改,后面訪問的時候只能讀取 3 print("這個裝飾器裝飾完了之后該方法可以像屬性一樣被呼叫") 4 return "年齡18歲" # 呼叫的時候可以直接呼叫屬性一樣來呼叫 5 print(t.read_attr) # t為實體化之后產生的物件
呼叫關系
類不可以呼叫實體方法,可以直接呼叫類方法,靜態方法
類屬性可以被實體方法呼叫,
魔術方法
python中有趣的玩意兒很多,魔術方法是一個大類,
什么是魔術方法?
python中雙下劃綫開頭,雙下劃綫結尾,
自定義方法的時候不要使用魔法方法命名方式,
拋出一個問題,我們常寫的init方法有什么作用?是不是實體化物件時最先運行的方法,
實體化類的程序
實體化類的時候會自動呼叫init方法,但是第一個執行的方法并非init,
__new__方法是在init方法之前執行的,這個方法在所有類的祖宗 object類里面,
object是所有類的祖宗,所有類默認繼承object
重寫__new__方法
知道這一點后,我們可以在類實體化的時候重寫new方法,加載一些私貨進取,
1 class MyClass(object): 2 def __init__(self, name): 3 self.name = name 4 5 def __new__(cls, *args, **kwargs): 6 print("這個是new方法") 7 return super().__new__(cls)
此處穿插一下,子類中呼叫父類方法的方式 super().method or 父類.父類mehtod 兩種呼叫方式去呼叫,
那么學會重寫new方法有什么運用呢?
單例模式
什么是單例模式?
不管實體化多少次,只回傳第一次創建的物件,即可得到這個物件中所有設定的屬性和方法,不會因再次實體化而發生丟失,
需求:類每次實體化都會創建一個新的物件,如果要求類只能被實體化一次,就用到了單例模式
單例模式的實作思路
new方法在init之前執行,
通過重寫new方法來對實力次數進行一個判斷,如果已經創建,則不再進行重新創建物件,只回傳第一次創建的物件,實作單例模式,
代碼思路,設定一個類屬性instance為None,重寫new方法并在new方法體內對instance進行判斷,如果為none就實體化,如果非none就呼叫父類的new方法吧物件賦值給instance
1 # 單例模式 2 class MyTest(object): 3 instance = None # 設定一個類屬性,用來記錄這個類有沒有創建過物件 4 def __new__(cls, *args, **kwargs): 5 # 判斷instance是否等于none 6 if not cls.instance: 7 cls.instance = super().__new__(cls) 8 return cls.instance 9 else: # 如果已經創建,不是空,就回傳原 就直接回傳原物件 10 # 回傳物件 11 return cls.instance
魔術方法三連 str,repr,call
思考一個問題,在python中print列印,與互動式變成直接列印有什么區別
使用print列印的時候觸發的事__str__方法,使用互動式的時候觸發的事repr方法
print方法列印出來的多是給用戶看的,repr這種互動式更多是方便程式員去查看資料型別
當然str也可以進行重寫,用來回傳一些提示資訊
重寫str,repr方法時一定要寫回傳值,且回傳值必須為字串
str方法的觸發
直接列印實體的時候會觸發
str方法處理實體的時候會觸發
format處理實體也會被觸發
repr方法的觸發
repr方法處理實體的時候會觸發
總結
使用str函式或者print列印物件時會優先觸發去尋找str方法,沒定義str方法的情況下會去找repr方法,如果都沒有,就會去找父類的str方法,
str--->repr--->object.str
使用repr方法或者互動環境下輸入變數,會先尋找自身的repr方法,沒有的話會去找父類的repr方法
Call方法
都說python中萬物接物件,函式也是物件,那么為什么函式可以加個括號就直接呼叫,而其他物件不能呢?
進一步說,如果想讓吧類實力出來的物件也可以像函式方法一樣加個括號就可以呼叫,需要怎么實作?
答案是通過call方法就可以實作上面的需求,
1 class MyClass1(): 2 def __init__(self, name): 3 self.name = name 4 5 def __str__(self): # 重寫 str 和repr 方法時必須要寫回傳 6 print("hhhhhh") 7 return "str方法的回傳值" 8 9 def __repr__(self): # 且回傳的必須是一個字串物件 10 print("233333") 11 return "repr方法的回傳值" 12 13 def __call__(self, *args, **kwargs): 14 print("像函式被呼叫的時候一樣被出發") 15 16 17 # str方法有三種方式出發 18 # 直接列印實體,str方法處理實體,format處理實體 19 m = MyClass1("adi") 20 print(m) 21 # repr(m) repr處理實體的時候會出發repr的魔法方法 22 repr(m) 23 m()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/117836.html
標籤:Python
