@classsmethod 類裝飾器:當用此裝飾器定義方法時,將類而不是類的實例作為第一個參數(shù),這意味著可以在此方法中直接使用類的屬性,而不是特定的實例的屬性,因此不必進行硬編碼。
@staticmethod 靜態(tài)裝飾器:當用此裝飾器定義方法時,不會傳遞類或實例作為它的參數(shù),這意味著可以在類中放置一個函數(shù)。靜態(tài)方法就是普通的函數(shù),只是碰巧在類的定義體中,而不是在模塊層定義。
在《流暢的Python》中,作者對這兩個裝飾器的評價:classmethod 裝飾器非常有用,但是我從未見過不得不用 staticmethod 的情況。如果想定義不需要與類交互的函數(shù),那么在模塊中定義就好了。有時,函數(shù)雖然從不處理類,但是函數(shù)的功能與類緊密相關,因此想把它放在近處。即便如此,在同一模塊中的類前面或后面定義函數(shù)也就行了。
class Date(object):
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
date2 = Date.from_string('11-09-2012')
is_date = Date.is_date_valid('11-09-2012')
使用靜態(tài)方法寫基類,注意靜態(tài)方法使用了實例的硬編碼。
class Date:
def __init__(self, month, day, year):
self.month = month
self.day = day
self.year = year
def display(self):
return "{0}-{1}-{2}".format(self.month, self.day, self.year)
@staticmethod
def millenium(month, day):
return Date(month, day, 2000)
new_year = Date(1, 1, 2013) # Creates a new Date object
millenium_new_year = Date.millenium(1, 1) # also creates a Date object.
# Proof:
new_year.display() # "1-1-2013"
millenium_new_year.display() # "1-1-2000"
isinstance(new_year, Date) # True
isinstance(millenium_new_year, Date) # True
繼承之后,millenium方法就用不了了。
class DateTime(Date):
def display(self):
return "{0}-{1}-{2} - 00:00:00PM".format(self.month, self.day, self.year)
datetime1 = DateTime(10, 10, 1990)
datetime2 = DateTime.millenium(10, 10)
isinstance(datetime1, DateTime) # True
isinstance(datetime2, DateTime) # False
datetime1.display() # returns "10-10-1990 - 00:00:00PM"
datetime2.display() # returns "10-10-2000" because it's not a DateTime object but a Date object.
改成類方法,
@classmethod
def millenium(cls, month, day):
return cls(month, day, 2000)
就正確了
datetime1 = DateTime(10, 10, 1990)
datetime2 = DateTime.millenium(10, 10)
isinstance(datetime1, DateTime) # True
isinstance(datetime2, DateTime) # True
datetime1.display() # "10-10-1990 - 00:00:00PM"
datetime2.display() # "10-10-2000 - 00:00:00PM"
代碼來自下面的鏈接,答的很贊:
https://stackoverflow.com/questions/12179271/meaning-of-classmethod-and-staticmethod-for-beginner/