看原碼:
class Goods: discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return self.__price*self.discount def set_price(self,new_price): if new_price and type(new_price) is int: #這里保護了輸入的數據為合法數據 self.__price=new_price else: print('請輸入正確的價格數據') apple=Goods('蘋果',5) print(apple.discount)
首先我們有一個需求;商品的折扣是人為定的,與商品中的對象無關。即Goods中的折扣直接通過Goods去更改,而不是要先創建一個Goods對象再去改。因為這個折扣將對所有的商品生效的。
上面的代碼顯示:要先有了apple的基礎上才能去更改discount。如果再創建一個”banana“商品,其折扣仍舊是0.5,顯示這不是我們想要的效果。
故我們使用類方法@classmethod來解決這個問題。見代碼:
class Goods: __discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return self.__price*self.__discount def set_price(self,new_price): if new_price and type(new_price) is int: #這里保護了輸入的數據為合法數據 self.__price=new_price else: print('請輸入正確的價格數據') @classmethod def set_discount(cls,new_discount): #將self替代為cls,用於這個類 cls.__discount=new_discount return self.__discount apple=Goods('蘋果',6) Goods.set_discount(0.8) print(apple.price)
即把一個方法變成一個類中的方法,這個方法就直接可以被類調用,不需要依托任何對象。
當這個方法的操作只涉及靜態屬性的時候,就應該使用這個classmethod來裝飾這個方法。
再講到靜態方法的作用。
類中的方法,有一些不需要傳self,這個時候就要用到staticmethod來裝飾這個方法。同時當該類的屬性需要類中的方法進行初始時,也可以通過靜態方法裝飾器來解決這個問題。
例如:有一個登陸類,其屬性要有name,password。但這個name 和password怎么來的呢。我們不允許類外去創建時,就可以用到靜態方法。
見代碼:
class Login(): def __init__(self,name,pwd): self.name=name self.pwd=pwd def login(self):pass def get_usr_pwd(self): name=input('用戶名>>') pwd=input('密碼>>>') Login(name,pwd)
Login.get_usr_pwd()
在完全面向對象的程序中,如果一個函數即與類無關,也與對象無關,那么就用staticmethod。
靜態方法和類方法都是類調用的。
對象可以調用類方法和靜態方法嗎?
答案是可以的。一般情況下,推薦用類名調用。
類方法有一個默認參數cls代表這個類。可以用別的名詞來替代,但不建議用別的名詞。
靜態方法沒有默認參數,就像普通函數一樣。是可以傳參的。