Python中常见的方法有实例方法,类方法(classmethod)和静态方法(staticmethod),这几种方法有何区别呢?这里来总结一下。
实例方法
实例方法也许是最常用的方法了,第一个参数默认为self
(其实要是换成其他名称,也不会有任何问题,只不过不符合python的风格)。当我们调用实例方法时,一般需要先实例化对象再调用。
>>> class Demo:
... def foo(self):
... return id(self)
...
>>> demo=Demo()
>>> demo.foo()
139640401487128
>>> id(demo)
139640401487128
例子中,foo
返回自身实例的id,我们发现该方法返回的id与 demo 实例的 id 一致,说明运行时,demo 实例对象确实被传入了方法中。
假如直接用类去调用foo
方法呢?
>>> Demo.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() missing 1 required positional argument: 'self'
错误提示的很清楚,foo
方法缺少参数 ‘self’。我们知道, ‘self’ 就是指实例自身,所以我们可以手动传入一个实例对象:
>>> Demo.foo(demo)
139640401487128
方法可以正确调用。通常情况下,使用实例方法时,解释器会帮我们把实例对象作为第一个参数传入方法,无需手动。
>>> Demo.foo
<function Demo.foo at 0x7f008d705ea0>
>>> demo.foo
<bound method Demo.foo of <__main__.Demo object at 0x7f009086e518>>
>>> Demo.foo is demo.foo
False
这里说明两个 Demo.foo
和 demo.foo
对象(python中万物皆对象,方法也是个对象)不是同一个对象,demo.foo
是已经绑定到 demo
实例对象的方法,而Demo.foo
未绑定到任何实例。类似的,同一个类不同的实例,其方法也不是同一对象:
>>> Demo().foo is Demo().foo()
False
类方法(classmethod)
类方法与实例方法类似,只不过第一个参数传的是类本身,一般用cls
表示,类方法可以进行对类属性的操作。
>>> class Car:
... length = 5
... @classmethod
... def get_len(cls):
... print(cls)
... return cls.length
...
>>> Car.get_len()
<class '__main__.Car'>
5
>>> Car().get_len()
<class '__main__.Car'>
5
>>> id(Car.get_len) == id(Car().get_len)
>>> True
类方法是绑定于类的,无论是直接用类调用方法还是实例化后调用均可,由于类本身已经被解释器传入,此时如果手动传入一个类,会导致参数过多:
>>> Car.get_len(Car)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: get_len() takes 1 positional argument but 2 were given
静态方法
静态方法本身仅仅是一个普通方法,不需要传入任何特殊的参数。
>>> class Car:
... @staticmethod
... def get_len():
... return 5
...
>>> Car.get_len() == Car().get_len() == 5
True
>>> Car.get_len is Car().get_len
True
类似的,无论是直接用类调用方法还是实例化后调用均可,但静态方法也不会对类或者实例对象进行任何操作。Car.get_len is Car().get_len
结果为True,说明类方法不绑定任何对象。静态方法只是一个普通的方法,只不过恰好处于一个类里面而已。
小结
1.实例方法与实例相关,调用时会传入实例对象作为第一个参数;
2.类方法与类相关,调用时会传入该类作为第一个参数;
3.静态方法实际上跟其他对象没有关系,也无需传入任何特殊参数。
实际上,这几种方法的本质区别,就是传参的不同。