標籤:

為什麼Python類成員的調用和聲明必須有"this"?

Python的這種設計是作者從Modula-3中借鑒來的,在後面使用的情況看來,這個設計也是比較成功的。我們對比Python和C++討論一下這個問題:

Modula-3是上世紀80年代末數字設備公司(DEC)系統研究中心(SRC)和Olivetti研究中心(ORC)設計的一門語言。儘管這門語言沒有在業界廣泛的應用起來,但這麼語言對後面被發明的Java, Python, Caml, C# 都產生了很多的影響

首先,調用的時候要求指定"this",讓我們更明確的區分調用的是一個成員變數、函數或者是一個局部變數、函數。當我們讀到self.x或者self.meth(),即使我們不知道class的定義也能100%確定這裡調用的是一個成員變數或者方法。我們設想一下,在C++中,我們還可以通過查看並排除所有的局部變數的方式去確認變數是成員變數(假設全局變數很少見,即使出現也是"g_"這種很容易辨認的)。而在Python中,由於變數不需要額外的定義,這個辦法就失效了,唯一的辦法就只有看class的定義,所以this就成了必須的。 很多C++和Java的編碼規範中會規定成員函數或變數要有m_前綴,我們也可以看到這種編碼規範是十分必要的。

其次,由於this這個對當前實例的強制顯式引用,Python不需要引入任何新的語法就可以引用或者調用其它類(包括父類)的成員變數和函數。在C++中,如果我們想要在子類中調用父類的函數,我們需要用到::這個運算符;在Python中我們這麼寫baseclass.methodname(self, <argument list>)。Python的這種語法在實現子類的__init__()時特別有用,例如我們經常需要在子類中override父類的函數並且調用父類函數自身。

最後,就是性能上的些許考量:在Python的語言定義中,局部變數就是在函數體中賦值,並且沒有在全局顯式的聲明過的變數。當然在語言設計上,我們有很多的辦法去告訴解釋器、編譯器某個變數賦值是針對一個局部變數還是一個成員變數,但出於解釋性語言的性能考慮,最好是語義上的的規定。C++用變數必須顯示的聲明解決了這個問題,但Python沒有額外的變數聲明語法,如果僅僅是出於上面所說的目的引入類似C++的變數必須顯式的聲明就顯得太得不償失了。所以,self.var這種語法就是一個非常優美的解決方案。我們在函數里寫上self.var這種語法,解釋器就不用費力地在全局範圍內進行變數的查找。換句話說,局部變數和成員變數存在於兩個不同的命名空間,我們需要告訴Python我們用的是哪個空間。

著作權歸作者所有,任何轉載請聯繫作者獲得授權。

服務端開發群:365534424,本文僅授權51Reboot相關賬號發布。

我的博客:Reboot運維開發


推薦閱讀:

python及numpy,pandas易混淆的點
python2.7的sort函數默認採用什麼排序演算法,適用於怎樣的數列的排序?
爬蟲入門到精通-網頁的解析(xpath)
*吧上有海外留學生問全部用遞歸求第N個質數,不能用循環
python Web 運維 爬蟲.....一條龍學習視頻教程

TAG:Python |