python類的實例方法\靜態方法\類方法區別解析(附代碼)

前言

搞了很久python,一直搞得不太清楚這幾種類的方法,今天花時間好好測試一下,算是弄懂點皮毛吧。python

三種方法的不一樣

先剽竊個圖看一下

能夠看到,實例是三種方法均可以調用的,而類只能夠調用兩種。因此這些方法的使用就是看你是否要讓類不須要經過實例來調用方法(類方法和靜態方法都不須要實例化成對象便可調用),而類方法和靜態方法的區別就是你是否要在該方法引用類的屬性或者其餘類的類方法。
可能仍是看不太懂吧,繼續看。函數

實例

這實際上是參考stackoverflow問答裏一位大神的回覆稍微改了改測試

  • 先解析下這腳本幹啥的:
    就是有個類叫Data_test,而後實例化i = Data_test('2016','1','1')它能把結果按格式輸出出來,打印年月日,但恰恰有的人比較賤,非要往裏傳一個"2016-1-1"這樣的字符串,咱們的類該怎麼辦呢。.net

    class Data_test(object):
        day=0
        month=0
        year=0
        forclass = 250
        def __init__(self,year=0,month=0,day=0):
            self.day=day
            self.month=month
            self.year=year
    
        @classmethod
        def get_date_class(cls,data_as_string): # 能夠傳參,cls即爲類自身
            year,month,day=map(int,data_as_string.split('-'))
            return cls(year,month,cls.forclass)  # 由於類方法能夠傳參一個cls參數,因此能夠調用類的相關信息,而靜態方法只是一個獨立的函數,恰巧放在了類裏,他跟這個類有關係(邏輯上的關係,好比是爲此類服務的,但無實質的交互),與類中的其餘方法或屬性無交互。這裏邊傳遞了一個類屬性250
    
        @staticmethod
        def get_date_static(data_as_string):  # 不能傳遞和類或實例相關的參數,如cls或self,但能夠傳遞其餘參數
            year,month,day=map(int,data_as_string.split('-'))
            return Data_test(year,month,day)
    
        def out_date(self):  # 最多見的實例方法
            print "year :"
            print self.year
            print "month :"
            print self.month
            print "day :"
            print self.day
    
    # 類方法和靜態方法調用方式一致,類名.方法名(參數),注意類名後邊沒有() 
    # 若是有括號至關於i=Data_test()實例化以後,再調用類方法i.get_date_class(),這樣就多建立了一個對象i,雖然結果一致,但意義不一樣了。
    # 另外再多說一句,若是i=Data_test(),以後直接去調用i()(對象名+括號),會自動調用類中的def __call__(self):方法,若是沒定義就會報錯,這裏扯遠了,和本文無關
    c=Data_test.get_date_class("2015-5-5")
    c.out_date()
    s=Data_test.get_date_static("2016-6-6")
    s.out_date()
  • 看下結果code

    year :
    2015
    month :
    5
    day :
    250  # 這裏被cls.forclass覆蓋了
    year :
    2016
    month :
    6
    day :
    6
  • 這裏可能有個疑問,若是不用靜態方法或者類方法,如何實現上邊的功能呢。對象

    # 若是不用類方法或者靜態方法呢,還想支持2015-5-5的時間格式,怎麼辦呢
    # 方法1:在類外邊定義一個函數,而後先經過此函數處理,將處理的結果傳入類的參數裏,這確定不是好的方法,自己get_date_instance只爲Data_test服務的,但如今卻又脫離在他以外了。  
    def get_date_instance(data_as_string):
        year,month,day=map(int,data_as_string.split('-'))
        result = {}
        result['year'] = year
        result['month'] = month
        result['day'] = day
        return result
    # 調用
    i=Data_test(**get_date_instance("2016-6-6"))
    i.out_date()
    
    # 方法2:從新定義類的__init__方法,對傳入的值進行判斷,若是爲2016-6-6這種格式,對他進行格式化,至關於把get_date_instance函數的內容放到__init__裏了,這樣的壞處就是不靈活,若是重構get_date_instance的邏輯,須要動__init__,不便於維護

參考資料

http://stackoverflow.com/questions/12179271/python-classmethod-and-staticmethod-for-beginner/12179325#12179325
http://blog.csdn.net/a447685024/article/details/52424481blog

相關文章
相關標籤/搜索