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())