Python面向對象之靜態方法和類方法

常規的類定義中,全部函數都被假定在實例上操做,該實例老是做爲第一個參數self傳遞。但還有能夠定義兩種常見的方法。函數

靜態方法是一種普通函數,它不會對任何實例類型進行操做。使用@staticmethod裝飾器來定義靜態方法:spa

  1: class Foo(object):
  2:     @staticmethod
  3:     def add(x, y):
  4:         return x + y
  5: 
  6: x = Foo.add(3, 4)

類方法是將類自己做爲對象進行操做的方法。使用@classmethod裝飾器來定義類方法,與普通的實例方法不一樣,由於根據約定,類是做爲第一個參數(名爲cls)傳遞:code

  1: class Times(object):
  2:     factor = 1
  3:     @classmethod
  4:     def mul(cls, x):
  5:         return cls.factor * x
  6: class TwoTimes(Times):
  7:     factor = 2
  8: x = TwoTimes.mul(4)

下面是一個類方法解決一個子類在調用基類中兩種方法設定的函數時,返回的不是子類自己的問題的例子:對象

  1: import time
  2: class Date(object):
  3:     def __init__(self, year, mon, day):
  4:         self.year = year
  5:         self.mon = mon
  6:         self.day = day
  7:     @classmethod
  8:     def now(cls):
  9:         t = time.localtime()
 10:         return cls(t.tm_year, t.tm_mon, t.tm_mday)
 11: class EuroDate(Date):
 12:     def __str__(self):
 13:         return "%02d/%02d/%4d" % (self.day, self.mon, self.year)
 14: a = Date.now() # 調用Date.now(Date)並返回Date
 15: b = EuroDate.now()  # 調用Date.now(EuroDate)

關於靜態方法和類方法須要注意的一點是,Python不會在實例方法獨立的命名空間中管理它們,因此能夠直接在實例上調用。
這極可能會引發混淆:it

  1: a = Date(1967, 4, 9)
  2: b = a.now()  # Date.now(Date)

由於a.now()的調用與實例a沒有任何關係。這種行爲是Python對象系統與其餘面嚮對象語言(如Ruby)對象系統的區別之一。在這些語言中,類方法與實例方法是嚴格分開的。class

相關文章
相關標籤/搜索