眾所周知,類是創(chuàng)建實(shí)例的模板,而實(shí)例是一個(gè)個(gè)具體的對(duì)象,各個(gè)實(shí)例擁有的數(shù)據(jù)相互獨(dú)立、互不影響。
在類中定義的函數(shù)稱為方法,主要有三種:實(shí)例方法、類方法、靜態(tài)方法
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 定義的三個(gè)方法分別是實(shí)例方法、類方法、靜態(tài)方法,下面我們來(lái)詳細(xì)分析
實(shí)例方法
不帶裝飾器的實(shí)例方法在類定義中是最常見的:
定義中,傳入的第一個(gè)參數(shù)必須是 self,表示實(shí)例本身,在其中可使用 self.attr 獲取實(shí)例的屬性。
a = A()
a.instance_method(2)
print(A.bar)
print(a.bar)
下面是程序運(yùn)行結(jié)果:
self <__main__.A object at 0x0000028554C87E48>
grg
grg
當(dāng)我們創(chuàng)建了實(shí)例 a 之后,調(diào)用 a.instance_method(2) 時(shí),實(shí)例 a 會(huì)被自動(dòng)傳入函數(shù)作為 self 參數(shù)。
如果我們調(diào)用 A.instance_method(2) 時(shí)會(huì)發(fā)生什么呢?即,類能不能調(diào)用實(shí)例方法?
Traceback (most recent call last):
File "I:\Program Code\Python\test2.py", line 32, in <module>
A.instance_method(2)
TypeError: instance_method() missing 1 required positional argument: 'n'
可以看到,數(shù)字 2 被傳入 self 參數(shù)了,所以才會(huì)提示缺少一個(gè)位置參數(shù) n,所以,實(shí)例方法不能由類調(diào)用。
順便提一句,屬性也分實(shí)例屬性和類屬性,上例直接定義的是類屬性,類和類實(shí)例都可以訪問(wèn)。類中定義的方法也可以無(wú)限制訪問(wèn)這個(gè)類屬性。
通過(guò) __init__(self,attr) 定義的是實(shí)例屬性,只有實(shí)例能訪問(wèn),類不能訪問(wèn)。類中定義的屬性只有傳進(jìn)了 self 參數(shù)的方法(通常就是實(shí)例方法)可訪問(wèn)。
classmethod
無(wú)需實(shí)例化,但與實(shí)例方法第一個(gè)參數(shù)必須是 self 類似,類方法第一個(gè)參數(shù)表示類自身的 cls 參數(shù),可以來(lái)調(diào)用類的屬性、類的方法、類的實(shí)例化對(duì)象等
a.class_method(2)
A.class_method(2)
觀察上面代碼的運(yùn)行結(jié)果:
cls <class '__main__.A'>
cls <class '__main__.A'>
可知,類方法既可以由類調(diào)用,也可以由實(shí)例調(diào)用。
再來(lái)看一個(gè)例子:
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)
運(yùn)行結(jié)果如下:
A song of Ice and Fire
The Marvel
上面,類方法創(chuàng)建了一個(gè)類實(shí)例。
staticmethod
無(wú)需 self 參數(shù),無(wú)需 cls 參數(shù),直接聲明一個(gè)靜態(tài)方法,可無(wú)需實(shí)例化,直接由類調(diào)用,也可實(shí)例化后調(diào)用。
帶 staticmethod 裝飾器定義的就是靜態(tài)方法,與普通函數(shù)沒(méi)有區(qū)別,可以不加參數(shù),可以加任意參數(shù),不必傳入 self ,既可以由實(shí)例調(diào)用,也可以由類調(diào)用。
A.static_method()
a.static_method()
運(yùn)行結(jié)果如下:
this is a static method
this is a static method
總結(jié)
實(shí)例方法只能由實(shí)例調(diào)用,類方法和靜態(tài)方法可以由實(shí)例或類調(diào)用。