Python中的類方法和靜態方法


看原碼:

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代表這個類。可以用別的名詞來替代,但不建議用別的名詞。

靜態方法沒有默認參數,就像普通函數一樣。是可以傳參的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM