@classmethod
有的時候在類中會有一種狀況,就是這個方法並不須要使用每個對象屬性
所以 這個方法中的self
參數一個徹底無用的參數,使用classmethod
python
class A: __count = 0 # 隱藏類count屬性 def __init__(self, name): self.name = name self.__add_count() # 每一次實例化的時候掉 # 用私有方法來對__count 進行累加 @classmethod def __add_count(cls): # 定義一個私有方法 print(cls, A) A.__count += 1 # 讓這個方法只能在類的內部被使用 @classmethod def show_count(cls): # 被classmethod 裝飾去的方法, print(cls.__count) return A.__count # 讓用戶能夠從外部查看__count的值 def show_count_self(self): # 定義一個普通方法 # print(self.__count) print(self) # print('_____') # print(self.show_count(),'fogogo') # return A.__count # 讓用戶能夠從外部查看__count的值 # show_count 是一個查看類中屬性的方法,這樣的方法和某一個對象並無直接聯繫 obj = A('baozi') print(A._A__add_count) # # 執行結果 <class '__main__.A'> <class '__main__.A'> <bound method A.__add_count of <class '__main__.A'>>
本質上 :函數
@classmethod
code
一個方法不用對象屬性可是使用靜態屬性 -- 類方法@classmethod
某一個方法被創造出來,就是爲了進行對靜態變量進行操做對象
@staticmehtod
get
根本不涉及到對象,因此這個方法就應該被定義成 類方法(被@classmethod
裝飾)
調用這個類方法,可使用對象調用,也可使用類調用
可是這個方法的默認參數永遠是當前類的命名空間,而不是對象的it
@staticmethod
若是一個類中的方法不用 對象屬性 也不用 靜態屬性 -- 靜態方法@staticmethod
table
那實際上這個方法就是一個普通的函數class
class User(object): @staticmethod def login(arg1, arg2):#是User類中的名字函數的名字login就是一個類中的靜態方法,本質上就是一個函數 return (arg1 + arg2) def show(self): print('---->show') print('---self--',self.login(1, 3)) print('class--',User.login(123, 31)) print(User.login(1,2)) ## 不須要實例化,當函數使用 print(User().show()) # 執行結果 3 ---->show ---self-- 4 class-- 154
一個不須要用到對象命名空間中的變量的方法,就不是一個對象方法,就應該是一個普通的函數變量
類是直接在本身的空間找到類 類這個方法object
對象先在本身的空間找,找不到,就到類的空間找
classmethod
staticmethod
使用場景說明:self
只要用self
就是普通方法,只能用對象調
Classmethod
只要cls 就是類方法,能夠用類,能夠用對象
Staticmethod
啥用不用 就是靜態方法 ,能夠用類,能夠用對象
普通的方法 | 類方法 | 靜態方法 | |
---|---|---|---|
默認參數 | self |
cls | 無 |
操做變量 | 操做對象屬性 | 操做靜態屬性 | 既不操做對象屬性,也不操做類的屬性 |
所屬的命名空間 | 類 | 類 | 類 |
調用方式 | 對象 | 類/對象 | 類/對象 |
對應的裝飾器 | 無 | @classmethod | @staticmethod |
@property
把一個方法假裝成屬性,
下面例子中計算圓面積的公式
class Cirecle: def __init__(self, r): self.r = r @property def area(self): # 被property 裝飾器 裝飾的方法不能傳遞 除self之外參數 return pi * self.r ** 2 def perimeter(self): return self.r * pi * 2 c1 = Cirecle(5) print(c1.area) # 打印執行結果 78.53981633974483
某一個屬性須要被私有,可是有須要能夠被外部查看, 這種狀況,把這個屬性經過方法,`property 假裝成屬性
class Person: def __init__(self, name): self.__name = name # 不讓外面隨便修改 @property def get_name(self): return self.__name ari = Person('arimiage') print(ari.get_name) # 執行結果 arimiage
Property 修改屬性值
@funcname.setter
@funcname.deleter
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 isinstance(new_name, str): # if type(new_name) is str: self.__name = new_name #setattr裝飾的函數名叫什麼 #那麼這個函數中絕對不能夠對這個,函數名同名屬性進行修改( 函數名) @name.deleter def name(self): print('gogoog') del self.__name #這裏才執行刪除屬性操做 def get_name(self): return self.__name # def set_name(self,new_name): # if type(new_name) is str: # if isinstance(new_name,str): # self.__name == new_name ari = Person('arimiage') {'_Person__name': 'arimiage'} # print(Person.__dict__) print(ari.get_name) ari.name = 'fgo' {'_Person__name': 'fgo'} #對象空間 print(Person.__dict__) print(ari.__dict__) print(ari.name) del ari.name # 只是至關於調用被deleter裝飾的方法,並不至關於刪除name屬性 {} 對象空間爲空 # print(ari.__dict__) # 報錯