Python深入 特殊方法與多正規化

2021-08-21 09:24:06 字數 3798 閱讀 1581

特殊方法名的前後各有兩個下劃線。特殊方法又被成為魔法方法(magic method),定義了許多python語法和表達方式,正如我們在下面的例子中將要看到的。當物件中定義了特殊方法的時候,python也會對它們有「特殊優待」。比如定義了init()方法的類,會在建立物件的時候自動執行init()方法中的操作。

(可以通過dir()來檢視物件所擁有的特殊方法,比如dir(1))

python的運算子是通過呼叫物件的特殊方法實現的。比如:

'abc' + 'xyz'

# 連線字串

實際執行了如下操作:

'abc'.__add__('xyz')
所以,在python中,兩個物件是否能進行加法運算,首先就要看相應的物件是否有add()方法。一旦相應的物件有add()方法,即使這個物件從數學上不可加,我們都可以用加法的形式,來表達obj.add()所定義的操作。在python中,運算子起到簡化書寫的功能,但它依靠特殊方法實現。

python不強制使用者使用物件導向的程式設計方法。使用者可以選擇自己喜歡的使用方式(比如選擇使用+符號,還是使用更加物件導向的add()方法。特殊方法寫起來總是要更費事一點。

嘗試下面的操作,看看效果,再想想它的對應運算子

(1.8).mul(2.0)

true.or(false)

與運算子類似,許多內建函式也都是呼叫物件的特殊方法。比如

len([1,2,3])      # 返回表中元素的總數
實際上做的是

[1,2,3].__len__()
相對與len(),內建函式len()也起到了簡化書寫的作用。

嘗試下面的操作,想一下它的對應內建函式

(-1).abs()

(2.3).int()

下面是我們常見的表元素引用方式

li = [1, 2, 3, 4, 5, 6]

print(li[3])

上面的程式執行到li[3]的時候,python發現並理解符號,然後呼叫getitem()方法。

li = [1, 2, 3, 4, 5, 6]

print(li.__getitem__(3))

嘗試看下面的操作,想想它的對應

li.setitem(3, 0)

.delitem(『a』)

我們已經說過,在python中,函式也是一種物件。實際上,任何乙個有call()特殊方法的物件都被當作是函式。比如下面的例子:

class

samplemore

(object):

def__call__

(self, a):

return a + 5

add = samplemore() # a function object

print(add(2)) # call function

map(add, [2, 4, 5]) # pass around function object

add為samplemore類的乙個物件,當被呼叫時,add執行加5的操作。add還可以作為函式物件,被傳遞給map()函式。

當然,我們還可以使用更「優美」的方式,想想是什麼。

對於內建的物件來說(比如整數、表、字串等),它們所需要的特殊方法都已經在python中準備好了。而使用者自己定義的物件也可以通過增加特殊方法,來實現自定義的語法。特殊方法比較靠近python的底層,許多python功能的實現都要依賴於特殊方法。我們將在以後看到更多的例子。

他們可以給你的類增加魔力的特殊方法,如果你的物件實現(過載,重寫)了這些方法中的某乙個,那麼這個方法就會在特殊的情況下被 python 所呼叫,你可以定義自己想要的行為,而這一切都是自動發生的。下面所寫的多是python中自帶的方法,如果重寫過會有不同的效果。先寫一些常用的。

每個python物件都有乙個最基本的魔術方法,init。通過此方法我們可以定義乙個物件的初始操作。然而,當例項化類的時候,init並不是第乙個被呼叫的方法。實際上,還有乙個叫做new的方法,兩個共同構成了「建構函式」。new是用來建立類並返回這個類的例項, 而init只是將傳入的引數來初始化該例項。在物件生命週期呼叫結束時,del方法會被呼叫,可以將del理解為「析構函式」。

補充:首先要知道在物件導向程式設計中,例項化基本遵循建立例項物件、初始化例項物件、最後返回例項物件這麼乙個過程。python 中的 new 方法負責建立乙個例項物件,init 方法負責將該例項物件進行初始化,init是在當例項物件建立完成後(完成後)被呼叫的,然後設定物件屬性的一些初始值。

new是在例項建立之前被呼叫的,new可以決定是否呼叫init,或者說可以決定呼叫哪個類的init方法,因為它的任務就是建立例項然後返回該例項,是個靜態方法。也就是,newinit之前被呼叫,new的返回值(例項)將傳遞給init方法的第乙個引數,然後init給這個例項設定一些引數。

實際中,我們在實際使用中很少會用到new,除非你希望能夠控制類的建立。比如單例模式可以用重寫new方法來實現。如果要具體講解new,會涉及到元類的概念,這裡就不細說了。順道提一下單例模式。

單例模式(singleton pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某乙個類只有乙個例項存在。當你希望在整個系統中,某個類只能出現乙個例項時,單例物件就能派上用場。(就是建立乙個類之後,再例項化也都是乙個物件,位址是相同的,也可以不建立新的物件,只使用這乙個物件,但是為了防止其他人再建立新的物件,所以引入了單例模式)

簡單介紹下幾種建立單例模式的方法,還有很多種,篇幅有限就不介紹了。

1、使用模組

python 的模組就是天然的單例模式,因為模組在第一次匯入時,會生成 .pyc 檔案,當第二次匯入時,就會直接載入 .pyc 檔案,而不會再次執行模組**。因此,我們只需把相關的函式和資料定義在乙個模組中,就可以獲得乙個單例物件了。python中from…import…會將這個py檔案先執行一次,如果我們真的想要乙個單例類,可以考慮這樣做:

mysingleton.py

class

singleton

(object):

deffoo

(self):

pass

singleton = singleton()

這樣我們在需要使用這個物件的時候,直接在其他檔案中匯入這個檔案中的物件就可以了。

2、使用new方法實現(推薦)

Python深入特殊方法與多正規化

python一切皆物件,但同時,python還是乙個多正規化語言 multi paradigm 你不僅可以使用物件導向的方式來編寫程式,還可以用面向過程的方式來編寫相同功能的程式 還有函式式 宣告式等,我們暫不深入 python的多正規化依賴於python物件中的特殊方法 special metho...

Python深入01 特殊方法與多正規化

python深入01 特殊方法與多正規化 python 一切皆物件,但同時,python還是乙個多正規化語言 multi paradigm 你不僅可以使用物件導向的方式來編寫程式,還可以用面向過程的方式來編寫相同功能的程式 還有函式式 宣告式等,我們暫不深入 python的多正規化依賴於python...

Python深入01 特殊方法與多正規化

python一切皆物件,但同時,python還是乙個多正規化語言 multi paradigm 你不僅可以使用物件導向的方式來編寫程式,還可以用面向過程的方式來編寫相同功能的程式 還有函式式 宣告式等,我們暫不深入 python的多正規化依賴於python物件中的特殊方法 special metho...