1. 程式人生 > >Python面向對象之靜態方法和類方法

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

pac local 面向對象語言 borde border time cme def 靜態方法

常規的類定義中,所有函數都被假定在實例上操作,該實例總是作為第一個參數self傳遞。但還有可以定義兩種常見的方法。

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

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

類方法是將類本身作為對象進行操作的方法。使用@classmethod裝飾器來定義類方法,與普通的實例方法不同,因為根據約定,類是作為第一個參數(名為cls)傳遞:

  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不會在實例方法獨立的命名空間中管理它們,所以可以直接在實例上調用。
這很可能會引起混淆:

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

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

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