面向對象的各種方法
靜態方法 - @staticmethod
class Person(): name = "cool guy" @staticmethod def static(self): print("staticmethod", self.name) if __name__ == "__main__": p = Person() p.static()
執行結果
p.static()
TypeError: static() missing 1 required positional argument: 'self'
為什么會報錯?
靜態方法不能訪問實例屬性、類屬性、實例方法、類方法
靜態方法的特別之處
- 它跟類與對象無關
- 跟在模塊中直接定義普通函數沒有什么區別,只是把“靜態方法”放到了類里面,所以只能設置形參
- 只能通過 類名.靜態方法 來調用
正確調用寫法
class Person(): name = "cool guy" @staticmethod def static(name): print("staticmethod", name) if __name__ == "__main__": p = Person() Person.static(p.name)
執行結果
staticmethod cool guy
類方法 - @classmethod
class person: name = "cool man" @classmethod def class_m(cls): print("--第一個類方法--", id(cls)) print("--第一個類方法--", cls.name) cls.self_m(cls) cls.class_m2() def self_m(self): print("--實例方法--", id(self)) print("--實例方法--", self.name) @classmethod def class_m2(cls): print("--第二個類方法--", id(cls)) p = person() p.name = "bad boy" # 綁定實例屬性 p.class_m() person.class_m()
執行結果
--第一個類方法-- 2381398112712 --第一個類方法-- cool man --實例方法-- 2381398112712 --實例方法-- cool man --第二個類方法-- 2381398112712 --第一個類方法-- 2381398112712 --第一個類方法-- cool man --實例方法-- 2381398112712 --實例方法-- cool man --第二個類方法-- 2381398112712
知識點
- 類方法內部可以直接訪問類屬性、類方法、實例方法
- cls 可以理解成類對象的引用,哪一個類對象調用的方法, cls 就是哪個一個類的引用, 類對象.類方法 ;和實例方法中的 self 很像, 實例對象.實例方法
- 調用其他類方法時,不用傳遞cls參數;但調用其他實例方法時,需要傳遞cls參數
- 在類方法內部調用的實例方法,接收的是一個類對象而不是實例對象,當實例對象綁定實例屬性時,在實例方法中打印的仍然是類屬性;表明類方法無法訪問實例屬性
- 一個類只有一個類對象,即使通過實例對象調用類方法,傳遞的仍然是類對象的引用,所有類方法都被同一個類對象調用
思考題
如果方法內部 即需要訪問 實例屬性,又需要訪問 類屬性,應該定義成什么方法?
答案:實例方法,因為可以通過 類對象.類屬性 來訪問,但在類方法中無法訪問實例屬性
class Person: name = "cool man" def self_m(self): Person.name = "yep" print(self.name) p = Person() p.name = "bad boy" # 綁定實例屬性 p.self_m() Person.self_m(Person)
執行結果
bad boy
yep
知識點
類對象調用實例方法時,需要傳遞類對象