前言

通常情况下,在类中定义的所有函数(注意了,这里说的就是所有,跟self啥的没关系,self也只是一个再普通不过的参数而已)都是对象的绑定方法,对象在调用绑定方法时会自动将自己作为参数传递给方法的第一个参数。
Python中的类也是一个普通对象,如果需要直接使用这个类,例如将类作为参数传递到其他函数中,又希望在实例化这个类之前就能提供某些功能,那么最简单的办法就是使用classmethod和staticmethod。这两者的区别在于在存在类的继承的情况下对多态的支持不同。所以本质上来说,面向对象中实例方法有哪些作用,classmethod也就有哪些作用,只是这个面向的“对象”是类本身而已。这和C++中的static method其实是不同的,C++中的static method只有命名空间的作用,而Python中不管是classmethod还是staticmethod都有OOP、多态上的意义。

实例方法(普通方法)

一个基本的实例方法如下所示:

1
2
3
4
5
6
7
8
9
class Kls(object):
def __init__(self, data):
self.data = data
def printd(self):
print(self.data)
ik1 = Kls('arun')
ik2 = Kls('seema')
ik1.printd()
ik2.printd()

普通方法

  • 1、2参数传递给方法
  • 3 self参数指向当前实例自身
  • 4 Python解释器将实例自身传递给方法

静态方法(staticmethod)

1
2
3
4
5
6
7
class Pizza:
@staticmethod
def mix_ingredients(x, y):
return x + y

def cook(self):
return self.mix_ingredients(self.cheese, self.vegetables)

静态方法mix_ingredients属于 Pizza class,但是 Pizza类和实例都可以调用该方法.

1
2
3
4
5
6
>>> Pizza.mix_ingredients
<function mix_ingredients at 0x10eb1ca28>
>>> Pizza().mix_ingredients
<function mix_ingredients at 0x10eb1ca28>
>>> Pizza().cook is Pizza().cook
False

也就是说Python并没有为Pizza对象实例化静态方法mix_ingredients.
staticmethod的用途:

  • 代码易读性.静态方法并不需要self参数
  • 节约内存.不用每个实例都实例化方法.
  • 在类内部控制静态方法.不然的话换一种实现方法,把函数放在在类外部……

类方法(classmethod)

1
2
3
4
5
6
7
class Pizza(object):
def __init__(self, ingredients):
self.ingredients = ingredients

@classmethod
def from_fridge(cls, fridge):
return cls(fridge.get_cheese() + fridge.get_vegetables())

这里的class method, from_fridge( cls, fridge)返回Pizza对象,这个Pizza是冰箱里的Pizza.假如我们用静态方法来写的话,还需要在函数中hardcode the Pizza class name,继承Pizza.
总结起来就是:class method可以用来为一个类创建一些预处理的实例.

调用staticmethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Pizza(object):
def __init__(self, radius, height):
self.radius = radius
self.height = height

@staticmethod
def compute_area(radius):
return math.pi * (radius ** 2)

@classmethod
def compute_volume(cls, height, radius):
return height * cls.compute_area(radius)

def get_volume(self):
return self.compute_volume(self.height, self.radius)

类方法