1. 程式人生 > 實用技巧 >python學習第18天----屬性、類方法、靜態方法

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.
591836734693878
View Code

問題:對於如上程式雖然實現了功能,但是BMI值是一個名詞(就應該封裝到屬性中),但是上述程式是通過一個方法計算出來的,相當於一個動詞

1)屬性:將一個方法偽裝成一個屬性,在程式碼的級別上沒有本質的提升,但是讓其看起來更加合理了

2)使用:在方法前加上@property這個裝飾器,修飾方法,那麼這個方法在呼叫時就不需要加括號了

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)) p1 = People("Tom",60,1.75) p1.EX 輸出: Tom的BMI值為19.591836734693878
View Code

3)將一個方法偽裝後的屬性改值

#如果在類中被@property @方法名.setter裝飾器修飾的方法都存在,然後對被偽裝的屬性改值,那麼就會自動執行被

@方法名.setter修飾的方法,並且將要改的值傳給被@方法名.setter裝飾器修飾的方法的self引數後的引數

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
666
View 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
阿狸18
View Code

#通過類方法時,不再需要建立物件

class Person:
    name = "阿狸"
    age = 18
    @classmethod
    def func(cls):
        return cls.name+str(cls.age)
print(Person.func())
輸出:
阿狸18
View Code

②對類中的靜態變數進行改變時,要用到類方法

class Person:
    name = "阿狸"
    age = 18
    @classmethod
    def func(cls):
        return cls.name+str(cls.age)     #就不再通過【類名.變數】的方式去改變靜態變數
print(Person.func())
輸出:
阿狸18
View 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'>
22
View Code
3.靜態方法

1)通過裝飾器@staticmethod修飾的方法,不需要給方法傳遞任何的引數,即相當於在類中定義了一個普通函式,不需要傳遞物件、類等引數

class A:
    @staticmethod
    def func():       #靜態方法
        print(666)
A.func()
輸出:
666
View Code

2)靜態方法優點

①在整體程式碼解構來說,使用靜態方法(將方法寫到類中)比較清晰,是一個程式碼塊

②靜態方法可提高程式碼的複用性

4.python2.xpython3.x的區別

1python2.x:各種大牛按照自己程式碼的習慣給python貢獻原始碼(java的原始碼習慣,C#原始碼的小習慣),導致原始碼混亂,重複

python2.x中的輸出是print() print

python2.x中的range就是一個列表[1,2,3]

python2.x中的輸入時raw_input(); input()只允許輸入數字

模組、專案等等區別

2python3.x:龜叔重寫,原始碼優美、清晰、簡單,2020python2.x不再更新

python3.x中的輸出是print()

Python3.x中,range是一個可迭代物件

python中的輸入是input()

模組、專案等等區別

3)將一個方法偽裝後的屬性改值

 如果在類中被@property @方法名.setter裝飾器修飾的方法都存在,然後對被偽裝的屬性改值,那麼就會自動執行被@方法名.setter修飾的方法,並且將要改的值傳給被@方法名.setter裝飾器修飾的方法的self引數後的引數