python學習第18天----屬性、類方法、靜態方法
1.屬性
引:計算一個人的MBI值
class People: def __init__(self,name,weight,hight): self.name = name self.__weight = weight self.__hight = hight def EX(self): result = self.__weight/(self.__hight**2) print("%s的BMI值為%s"% (self.name,result)) p1 = People("Tom",60,1.75) p1.EX() 輸出: Tom的BMI值為19.View Code591836734693878
問題:對於如上程式雖然實現了功能,但是BMI值是一個名詞(就應該封裝到屬性中),但是上述程式是通過一個方法計算出來的,相當於一個動詞
1)屬性:將一個方法偽裝成一個屬性,在程式碼的級別上沒有本質的提升,但是讓其看起來更加合理了
2)使用:在方法前加上@property這個裝飾器,修飾方法,那麼這個方法在呼叫時就不需要加括號了
class People: def __init__(self,name,weight,hight): self.name = name self.__weight = weight self.View Code__hight = hight @property def EX(self): #偽裝成屬性 result = self.__weight/(self.__hight**2) print("%s的BMI值為%s"% (self.name,result)) p1 = People("Tom",60,1.75) p1.EX 輸出: Tom的BMI值為19.591836734693878
3)將一個方法偽裝後的屬性改值
#如果在類中被@property和 @方法名.setter裝飾器修飾的方法都存在,然後對被偽裝的屬性改值,那麼就會自動執行被
class People: def __init__(self,name,weight,hight): self.name = name self.__weight = weight self.__hight = hight @property def EX(self): #偽裝成屬性 result = self.__weight/(self.__hight**2) print("%s的BMI值為%s"% (self.name,result)) @EX.setter def EX(self,a1): print(a1) print("自動被執行。。。") p1 = People("Tom",60,1.75) p1.EX = 18 #不需要括號,直接呼叫 輸出: 18 666View Code
注:若要改屬性的值,兩個裝飾器缺一不可
#例:修改被偽裝的屬性的值
class Person: def __init__(self,name,age): self.name = name self.__age = age @property def age(self): return self.__age @age.setter def age(self,a1): if type(a1) is int: self.__age = a1 else: print("你輸入的值有誤") p1 = Person("阿狸",18) print(p1.age ) p1.age = 20 print(p1.age) 輸出: 18 20 說明:首先例項化一個物件,傳進去阿狸和18,例項化時自動執行__init__方法,執行時封裝了一個名字name;p1.age讓別然看來呼叫的就是p1物件的屬性,@procerty就是將age方法偽裝成一個屬性,然後通過p1.age相當於執行age方法,返回__age私有變數值;p1.age = 20是對屬性進行改變,只要值一改變就會自動的執行被@age.setter修飾的方法,並且將要改變的值傳給方法的第二個引數View Code
4)刪除被偽裝的屬性【方法名.delerter】
class Person: def __init__(self,name,age): self.name = name self.__age = age @property def age(self): return self.__age @age.setter def age(self,a1): if type(a1) is int: self.__age = a1 else: print("你輸入的值有誤") @age.deleter def age(self): print("使用del,自動被執行..") del self.__age #刪除私有變數 p1 = Person("阿狸",18) print(p1.age ) del p1.age 輸出: 18 使用del,自動被執行..View Code
總結:可理解為一個執行觸發一個方法
5)使用場景:property用於類似於求BMI這種,看似是一個名詞,但是實際需要計算的,都用property裝飾
2.類方法
#通過物件呼叫類的普通方法,會將物件地址傳給普通方法的引數self
class A: def func(self): #普通方法 print(self) a1 = A() a1.func() #通過物件呼叫普通方法 A.func(a1) #通過類名呼叫普通方法 輸出: <__main__.A object at 0x0000025F5AB75EB8> <__main__.A object at 0x0000025F5AB75EB8>View Code
1)類方法:就是在普通方法前,通過裝飾器@classmethod修飾,再通過類名呼叫的方法,類方法種第一個引數約定俗成為cls,python自動將類名(類空間)傳給cls
class A: @classmethod def func(cls): #類方法 print(cls) A.func() 輸出: <class '__main__.A'>View Code
#如果是物件呼叫類方法,cls得到的是類本身
class A: @classmethod def func(cls): #類方法 print(cls) a = A() a.func() 輸出: <class '__main__.A'>View Code
2)類方法應用場景
①類中有些方法是不需要傳入物件的,即不要物件的一起東西
#對於如下程式,完全不需要例項化物件,但是直接用類名呼叫函式會出錯,需要再類名呼叫函式時傳參
class Person: name = "阿狸" age = 18 def func(self): return Person.name+str(Person.age) print(Person.func(1)) p = Person() print(p.func()) 輸出: 阿狸18 阿狸18View Code
#通過類方法時,不再需要建立物件
class Person: name = "阿狸" age = 18 @classmethod def func(cls): return cls.name+str(cls.age) print(Person.func()) 輸出: 阿狸18View Code
②對類中的靜態變數進行改變時,要用到類方法
class Person: name = "阿狸" age = 18 @classmethod def func(cls): return cls.name+str(cls.age) #就不再通過【類名.變數】的方式去改變靜態變數 print(Person.func()) 輸出: 阿狸18View Code
③繼承中,父類得到子類的類空間(父類可對子類的所以內容進行修改)
class A: @classmethod def func(cls): #類方法 print(cls) #父類中得到了子類的類空間 print(cls.age) class B(A): age = 22 def func_b(self): pass B.func() #子類呼叫方法,先在子類找,子類找不到,去父類找,父類就得到了子類的類空間 輸出: <class '__main__.B'> 22View Code
3.靜態方法
1)通過裝飾器@staticmethod修飾的方法,不需要給方法傳遞任何的引數,即相當於在類中定義了一個普通函式,不需要傳遞物件、類等引數
class A: @staticmethod def func(): #靜態方法 print(666) A.func() 輸出: 666View Code
2)靜態方法優點
①在整體程式碼解構來說,使用靜態方法(將方法寫到類中)比較清晰,是一個程式碼塊
②靜態方法可提高程式碼的複用性
4.python2.x和python3.x的區別
1)python2.x:各種大牛按照自己程式碼的習慣給python貢獻原始碼(java的原始碼習慣,C#原始碼的小習慣),導致原始碼混亂,重複
①python2.x中的輸出是print() print
②python2.x中的range就是一個列表[1,2,3]
③python2.x中的輸入時raw_input(); input()只允許輸入數字
模組、專案等等區別
2)python3.x:龜叔重寫,原始碼優美、清晰、簡單,2020年python2.x不再更新
①python3.x中的輸出是print()
②Python3.x中,range是一個可迭代物件
③python中的輸入是input()
模組、專案等等區別
3)將一個方法偽裝後的屬性改值
如果在類中被@property和 @方法名.setter裝飾器修飾的方法都存在,然後對被偽裝的屬性改值,那麼就會自動執行被@方法名.setter修飾的方法,並且將要改的值傳給被@方法名.setter裝飾器修飾的方法的self引數後的引數