众所周知,类是创建实例的模板,而实例是一个个具体的对象,各个实例拥有的数据相互独立、互不影响。
在类中定义的函数称为方法,主要有三种:实例方法、类方法、静态方法
class A:
def instance_method(self, n):
print('self', self)
@classmethod
def class_method(cls, n):
print('cls', cls)
@staticmethod
def static_method():
print('this is a static method')
上面类 A 定义的三个方法分别是实例方法、类方法、静态方法,下面我们来详细分析
实例方法
不带装饰器的实例方法在类定义中是最常见的:
定义中,传入的第一个参数必须是 self
,表示实例本身,在其中可使用 self.attr
获取实例的属性。
a = A()
a.instance_method(2)
print(A.bar)
print(a.bar)
下面是程序运行结果:
self <__main__.A object at 0x0000028554C87E48>
grg
grg
当我们创建了实例 a 之后,调用 a.instance_method(2) 时,实例 a 会被自动传入函数作为 self 参数。
如果我们调用 A.instance_method(2) 时会发生什么呢?即,类能不能调用实例方法?
Traceback (most recent call last):
File "I:Program CodePython est2.py", line 32, in <module>
A.instance_method(2)
TypeError: instance_method() missing 1 required positional argument: 'n'
可以看到,数字 2 被传入 self 参数了,所以才会提示缺少一个位置参数 n,所以,实例方法不能由类调用。
顺便提一句,属性也分实例属性和类属性,上例直接定义的是类属性,类和类实例都可以访问。类中定义的方法也可以无限制访问这个类属性。
通过 __init__(self,attr)
定义的是实例属性,只有实例能访问,类不能访问。类中定义的属性只有传进了 self
参数的方法(通常就是实例方法)可访问。
classmethod
无需实例化,但与实例方法第一个参数必须是 self
类似,类方法第一个参数表示类自身的 cls
参数,可以来调用类的属性、类的方法、类的实例化对象等
a.class_method(2)
A.class_method(2)
观察上面代码的运行结果:
cls <class '__main__.A'>
cls <class '__main__.A'>
可知,类方法既可以由类调用,也可以由实例调用。
再来看一个例子:
class Book(object):
def __init__(self, title):
self.title = title
@classmethod
def create(cls, title):
book = cls(title)
return book
book1 = Book('A song of Ice and Fire')
book2 = Book.create('The Marvel')
print(book1.title)
print(book2.title)
运行结果如下:
A song of Ice and Fire
The Marvel
上面,类方法创建了一个类实例。
staticmethod
无需 self
参数,无需 cls
参数,直接声明一个静态方法,可无需实例化,直接由类调用,也可实例化后调用。
带 staticmethod 装饰器定义的就是静态方法,与普通函数没有区别,可以不加参数,可以加任意参数,不必传入 self ,既可以由实例调用,也可以由类调用。
A.static_method()
a.static_method()
运行结果如下:
this is a static method
this is a static method
总结
实例方法只能由实例调用,类方法和静态方法可以由实例或类调用。