天天看點

python類方法,靜态方法,執行個體方法,私有屬性

python中,類方法(@classmethod)和靜态方法(@staticmethod)都是為了對類參數進行一些預處理的過程,

友善使用不同參數對類的調用

靜态方法:

class Date:

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def __str__(self):
        return '{year}/{month}/{day}'.format(year=self.year, month=self.month, day=self.day)      
@staticmethod
    def parse_from_string(date_str):     #雖然是定義在類的内部,但靜态方法不需要用self參數,即不用執行個體本身作為參數
        year, month, day = tuple(re.split(r'-|\.', date_str))
        return Date(int(year), int(month), int(day))     #當類的名字更改時,此處名字也要改。為了解決這個問題,是以要使用類方法
      

          # 當執行個體化Date時,使用parse_from_string方法,傳入的參數可以接收單個字元串,然後再拆分成三個參數給

             構造函數__init__來生成執行個體,如下面:

if __name__ == '__main__':

        date_str = '2008-1-1'

        new_day = Date.parse_from_string(date_str)

        print(new_day)                                      //    列印2008/1/1

類方法:

如上所說,靜态是可以提前處理類的傳入參數。靜态方法不一定要傳回類本身,即靜态方法可以return 其他東西(如字元串,布爾值等)。但當靜态方法要傳回類本身的時候,如上面的例子,如果修改定義的類名,也要對靜态方法中的類名進行修改。為了避免這一個問題,可以采用類方法:

class Date:

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def __str__(self):
        return '{year}/{month}/{day}'.format(year=self.year, month=self.month, day=self.day)      
@classmethod
    def parse(cls, date_str):       #與靜态方法實作同樣的功能,隻是要添加類本身的參數,這裡的cls不是固定的,可以用其他變量來替換
        year, month, day = tuple(re.split(r'-|\.', date_str))
        return cls(int(year), int(month), int(day))      

         # 當執行個體化Date時,使用parse方法,傳入的參數可以接收單個字元串,然後再拆分成三個參數給

            構造函數__init__來生成執行個體,如下面:

if __name__ == '__main__':

        date_str = '2008-1-1'

        new_day = Date.parse(date_str)

        print(new_day)

私有屬性

python中,通過在屬性前添加雙下劃線可以讓一個類變量或者方法變成私有,外面是“不能”通路該屬性,繼承該類的子類也不能通路。注意,并不是絕對的不能通路,可能通過另外一個方法來通路到定義的私有屬性(執行個體名._類名.帶雙下劃線的私有屬性名)

class User:
    def __init__(self, birthday):
        self.__birthday = birthday   # __birthday就是私有屬性

    def get_age(self):
        return datetime.date.today().year - self.__birthday.year


if __name__ == '__main__':
    user = User(Date(2000, 1, 1))
    print(user.__birthday)       # 報錯,提示沒有該屬性
    print(user._User__birthday)  # 正常列印2001/1/1
    print(user.get_age())