Python面向对象之静态方法和类方法

常规的类定义中,所有函数都被假定在实例上操作,该实例总是作为第一个参数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)对象系统的区别之一。在这些语言中,类方法与实例方法是严格分开的。

原文地址:https://www.cnblogs.com/haoqirui/p/10040959.html