定义在类中的代码块叫方法,Python的方法分为『实例方法』、『类方法』、『静态方法』,按照从前到后的顺序它们和实例对象的依赖程度依次降低
class Demo:
sfield = 100 # 静态属性
def __init__(self, value):
''' 初始化方法 '''
self.value = value
def ixmethod(self):
''' 实例方法,测试能否调用实例属性 '''
print('ixmethod ->', self.value)
def iymethod(self):
''' 实例方法,测试能否调用静态属性 '''
print('iymethod ->', self.sfield)
def cxmethod(cls):
''' 伪·类方法,测试能否调用实例属性 '''
print('cxmethod ->', cls.value)
@classmethod
def cymethod(cls):
''' 真·类方法,测试能否调用静态属性 '''
print('cymethod ->', cls.sfield)
def sxmethod():
''' 伪·静态方法,尝试打印一条语句 '''
print('apple')
@staticmethod
def symethod():
''' 真·静态方法,尝试打印一条语句 '''
print('banana')
>>> d = Demo(1) # value初始值为1
>>> d.ixmethod()
ixmethod -> 1
>>> Demo.ixmethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ixmethod() missing 1 required positional argument: 'self'
>>> d.iymethod()
iymethod -> 100
>>> Demo.iymethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iymethod() missing 1 required positional argument: 'self'
>>> d.cxmethod()
cxmethod -> 1
>>> Demo.cxmethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cxmethod() missing 1 required positional argument: 'cls'
>>> d.cymethod()
cymethod -> 100
>>> Demo.cymethod()
cymethod -> 100
>>> d.sxmethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sxmethod() takes 0 positional arguments but 1 was given
>>> Demo.sxmethod()
apple
>>> d.symethod()
banana
>>> Demo.symethod()
banana
结论如下
1)类方法和静态方法必须要在方法头部加上@开始的修饰符,否则不能视为完全的类方法或静态方法;特别是类方法,如果没有加@开始的修饰符,效果和实例方法等价,因为self不是关键字,如果仅仅写下cls编译器并不能识别
2)按照实例方法、类方法、静态方法的顺序,它们对该类的依赖性逐渐降低:实例方法既可以方法实例属性,也可以方法静态属性(self调用);类方法只能调用静态属性(cls调用);而静态方法因为没有参数绑定到该类所以仅仅提供函数功能,不能调用实例属性或静态属性
3)类的实例对象在调用类中定义的方法时,会把自身作为第一个参数传进去(如果有参数的话),这也是为什么不写@classmethod的伪·类方法实际上还是实例方法的本质原因