1. 程式人生 > >為什麽Python類成員的調用和聲明必須有"this"?

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

span AS 運算 一個 由於 live var his http

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

技術分享圖片

Modula-3是上世紀80年代末數字設備公司(DEC)系統研究中心(SRC)和Olivetti研究中心(ORC)設計的一門語言。

盡管這門語言沒有在業界廣泛的應用起來,但這麽語言對後面被發明的Java, Python, Caml, C# 都產生了很多的影響

技術分享圖片

1.首先,調用的時候要求指定"this",讓我們更明確的區分調用的是一個成員變量、函數或者是一個局部變量、函數。

當我們讀到self.x或者self.meth(),即使我們不知道class的定義也能100%確定這裏調用的是一個成員變量或者方法。我們設想一下,在C++中,我們還可以通過查看並排除所有的局部變量的方式去確認變量是成員變量(假設全局變量很少見,即使出現也是"g_"這種很容易辨認的)。

而在Python中,由於變量不需要額外的定義,這個辦法就失效了,唯一的辦法就只有看class的定義,所以this就成了必須的。 很多C++和Java的編碼規範中會規定成員函數或變量要有m_前綴,我們也可以看到這種編碼規範是十分必要的。

2.其次,由於this這個對當前實例的強制顯式引用,Python不需要引入任何新的語法就可以引用或者調用其它類(包括父類)的成員變量和函數。

在C++中,如果我們想要在子類中調用父類的函數,我們需要用到::這個運算符;在Python中我們這麽寫baseclass.methodname(self, <argument list>)。Python的這種語法在實現子類的__init__()時特別有用,例如我們經常需要在子類中override父類的函數並且調用父類函數自身。

3.最後,就是性能上的些許考量:在Python的語言定義中,局部變量就是在函數體中賦值,並且沒有在全局顯式的聲明過的變量。

當然在語言設計上,我們有很多的辦法去告訴解釋器、編譯器某個變量賦值是針對一個局部變量還是一個成員變量,但出於解釋性語言的性能考慮,最好是語義上的的規定。C++用變量必須顯示的聲明解決了這個問題,但Python沒有額外的變量聲明語法,如果僅僅是出於上面所說的目的引入類似C++的變量必須顯式的聲明就顯得太得不償失了。

所以,self.var這種語法就是一個非常優美的解決方案。我們在函數裏寫上self.var這種語法,解釋器就不用費力地在全局範圍內進行變量的查找。換句話說,局部變量和成員變量存在於兩個不同的命名空間,我們需要告訴Python我們用的是哪個空間。

Python學習群:238757010

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