類中的三個裝飾器方法
阿新 • • 發佈:2018-11-26
@classmethod
class A: __count = 0 #隱藏count屬性 def __init__(self,name): self.name = name self.__add_count() #每一次例項化的時候呼叫私有化__count進行累加 def __add_count(self): #定義一個私有化的方法 A.__count +=1 def show_count(self): #定義一個普通方法 return A.__count #讓使用者可以從外部檢視__count的值def eat(self): print('%s在吃飯'%self.name) wl = A('wanglan') print(wl.show_count()) wl.eat() #有的時候,在類中會有一種情況,就是這個方法並不需要使用某一個物件的屬性,因此,這個方法中的self引數是一個完成無用的引數, #show_count是一個檢視類中屬性的方法,這樣的方法和某一個物件並沒有直接聯絡
在上面程式碼中,__add_count 方法和show_count方法並沒有使用self引數,但是我們給它傳了,正常情況下,如果引數不被使用,我們不應該傳入改引數,因此這個方法中的self引數是一個完全無用的引數,我們可以直接刪除,刪除後的報錯也只是Pycharm上的語法報錯,但是python的語法不希望我們這樣做,我們可以使用 @classmethod
class A: __count = 0 #隱藏count屬性 def __init__(self,name): self.name = name self.__add_count() #每一次例項化的時候呼叫私有化__count進行累加 @classmethod #被classmethod 裝飾器裝飾的方法,都用一個預設的引數,這個引數就是當前類 def __add_count(cls): #定義一個私有化的方法 print(cls,A) #兩個值相同 cls.__count+=1 # cls 就可以取代A @classmethod def show_count(cls): #定義一個普通方法 return cls.__count #讓使用者可以從外部檢視__count的值 def eat(self): print('%s在吃飯'%self.name) print(A.show_count()) #可以直接呼叫show_count wl = A('wanglan') print(wl.show_count()) wl.eat() 結果: 0 <class '__main__.A'> <class '__main__.A'> 1 wanglan在吃飯
本質上:一個方法不用物件屬性但是使用靜態屬性 -- 類方法(@classmethod)
某一個方法被創造出來,就是為了對靜態變數進行操作,根部不涉及到物件,所以這個方法就應該被定義成:類方法(被@classmethod裝飾),呼叫這個類方法時,可以使用物件呼叫wl.show_count(),也可以使用類呼叫 A.show_count(),但是這個方法的預設引數永遠是當前類的名稱空間,而不是物件
@staticmethod
def login(): #普通函式 pass login() #呼叫
純面向物件程式設計
class User(object): @staticmethod def login(): #是User類中的名字 函式的名字 login就是一個類中的靜態方法,本質上就是一個函式 pass ret = User.login()
如果一個類中的方法不用物件屬性也不用靜態熟屬性 -- 靜態方法(@staticmethod),實際上這個方法就是一個普通的函式
小結
普通的方法 類方法 靜態方法 預設引數 self cls 無 操作的變數 操作物件的屬性 操作靜態屬性 既不操作物件屬性,也不操作類的屬性 所屬的名稱空間 類 類 類 呼叫方式 物件 類/物件 類/物件 對應的裝飾器 無 @classmethod @staticmethod
@property:
把一個方法偽裝成屬性,和呼叫屬性一樣去呼叫方法()名稱裝飾,動詞就不用了)
某一個屬性如果是通過計算得來的,那麼計算的過程寫在方法裡,把這個方法偽裝成屬性
from math import pi class Circle: def __init__(self,r): self.r = r @property # 把一個方法偽裝成屬性 原始碼中有人寫, def area(self): # 被property裝飾器裝飾的方法不能傳遞除self以外的引數 return pi*self.r**2 @property def perimeter(self): return self.r*pi*2 c1 = Circle(5) # print(c1.area()) #加入@property 方法前的呼叫 print(c1.area) #加入@property 方法後的呼叫 c1.r = 10 print(c1.area)
某一個屬性需要被私有化,又需要能被外部檢視,這種情況,把這個屬性通過方法返回,方法偽裝成屬性
class Person: def __init__(self,name): self.__name = name # 不讓外面隨便修改 @property def name(self): return self.__name wl = Person('wanglan') print(wl.name)
修改屬性值
class Person: def __init__(self,name): self.__name = name # 不讓外面隨便修改 @property def name(self): return self.__name @name.setter # 之前必須有一個同名的方法被property裝飾過 def name(self,new_name): if type(new_name) is str: self.__name = new_name @name.deleter def name(self): del self.__name wl= Person('wang') print(wl.name) wl.name = 'wanglan' print(wl.name) del wl.name # 只是相當於呼叫被deleter裝飾的方法,並不相當於刪除name屬性 print(wl.name)