類中定義的方法可以是:
- @classmethod 裝飾的類方法,第一個(gè)參數(shù)必須是cls署辉。使用場(chǎng)景:作為工廠方法創(chuàng)建實(shí)例對(duì)象碱鳞。
- 可以是 @staticmethod 裝飾的靜態(tài)方法,參數(shù)根據(jù)業(yè)務(wù)需求定,可有可無(wú)挎袜。
使用場(chǎng)景:如果在方法中不需要訪問任何實(shí)例方法和屬性檐春,純粹地通過傳入?yún)?shù)并返回?cái)?shù)據(jù)的功能性方法逻淌,那么它就適合用靜態(tài)方法來(lái)定義,它節(jié)省了實(shí)例化對(duì)象的開銷成本疟暖,往往這種方法放在類外面的模塊層作為一個(gè)函數(shù)存在也是沒問題的卡儒,而放在類中,僅為這個(gè)類服務(wù)俐巴。(staticmethod相當(dāng)于定義了一個(gè)局部域函數(shù)為該類專門服務(wù)) - 用的最多的還是不帶裝飾器的實(shí)例方法骨望,第一個(gè)參數(shù)必須是 self。
class A(object):
def m1(self, n):
print("self:", self)
@classmethod
def m2(cls, n):
print("cls:", cls)
@staticmethod
def m3(n):
pass
a = A()
a.m1(1) # self: <__main__.A object at 0x000001E596E41A90>
A.m2(1) # cls: <class '__main__.A'>
A.m3(1)
當(dāng)程序運(yùn)行時(shí):
? 第一步:代碼從第一行開始執(zhí)行 class 命令欣舵,此時(shí)會(huì)創(chuàng)建一個(gè)類 A 對(duì)象(沒錯(cuò)擎鸠,類也是對(duì)象,一切皆對(duì)象嘛)同時(shí)初始化類里面的屬性和方法缘圈,記住劣光,此刻實(shí)例對(duì)象還沒創(chuàng)建出來(lái)袜蚕。
? 第二、三步:接著執(zhí)行 a=A()绢涡,系統(tǒng)自動(dòng)調(diào)用類的構(gòu)造器牲剃,構(gòu)造出實(shí)例對(duì)象 a
? 第四步:接著調(diào)用 a.m1(1) ,m1 是實(shí)例方法垂寥,內(nèi)部會(huì)自動(dòng)把實(shí)例對(duì)象傳遞給 self 參數(shù)進(jìn)行綁定颠黎,也就是說(shuō), self 和 a 指向的都是同一個(gè)實(shí)例對(duì)象滞项。
第五步:調(diào)用A.m2(1)時(shí)狭归,python內(nèi)部隱式地把類對(duì)象傳遞給 cls 參數(shù),cls 和 A 都指向類對(duì)象文判。
Python中方法:
私有變量/方法: —> __xxx "雙下劃線 " 開始的成員變量叫做私有變量过椎。
雙下劃線 " 開始的是私有成員,此類變量只有類對(duì)象自己能訪問戏仓,連子類對(duì)象也不能訪問到這個(gè)數(shù)據(jù)疚宇。保護(hù)變量 —>_xxx "單下劃線 " 開始的成員變量叫做保護(hù)變量。 該類的實(shí)例和子類的實(shí)例能夠訪問保護(hù)變量赏殃。
_ xxx_ 系統(tǒng)定義名字敷待,前后均有一個(gè)“雙下劃線” 代表python里特殊方法專用的標(biāo)識(shí),如 _ init _()代表類的構(gòu)造函數(shù)仁热。
在內(nèi)部榜揖,python使用一種 name mangling技術(shù),將 __membername替換成 _classname__membername抗蠢,也就是說(shuō)举哟,類的內(nèi)部定義中,所有以雙下劃線開始的名字都被"翻譯"成前面加上單下劃線和類名的形式。
例如:為了保證不能在class之外訪問私有變量迅矛,Python會(huì)在類的內(nèi)部自動(dòng)的把我們定義的__spam私有變量的名字替換成為 _classname__spam(注意妨猩,classname前面是一個(gè)下劃線,spam前是兩個(gè)下劃線)秽褒,因此壶硅,用戶在外部訪問__spam的時(shí)候就會(huì)提示找不到相應(yīng)的變量。
在類的外部:_classname__spam 便可訪問該類的私有變量震嫉。