對Python應用程序進行剖析解讀
Python應用程序是一個真正面向?qū)ο蟮恼Z言,它只增加了很少的新語法就實現(xiàn)了類,它的類機制是C++ 和Modula-3的類機制的混合,Python的類并不嚴格限制用戶對定義的修改,它依賴于用戶自覺不去修改定義。
類繼承機制允許多個基類的繼承,導出類可以重載基類的任何方法,方法可以調(diào)用基類的同名方法。對象可以包含任意多的私有數(shù)據(jù)。用C++術(shù)語說,所有類成員(包括數(shù)據(jù)成員)是公用的,所有成員函數(shù)是虛擬(virtual)的。沒有特別的構(gòu)建函數(shù)或銷毀函數(shù)(destructor)。
如同在Modula-3中一樣,從對象的方法中要引用對象成員沒有簡捷的辦法:方法函數(shù)的必須以對象作為第一個參數(shù),而在調(diào)用時則自動提供。象在Smalltalk中一樣,類本身也是對象,實際上這里對象的含義比較寬:在Python 中所有的數(shù)據(jù)類型都是對象。
象在C++或Modula-3中一樣,內(nèi)置類型不能作為基類由用戶進行擴展。并且,象C++但不象Modula-3,多數(shù)有特殊語法的內(nèi)置函數(shù)(如算術(shù)算符、下標等)可以作為類成員重定義。
Python應用程序的對象概念比較廣泛,對象不一定非得是類的實例,因為如同C++和Modula-3而不同于Smalltalk,Python的數(shù)據(jù)類型不都是類。比如基本內(nèi)置類型整數(shù)、列表等不是類,甚至較古怪的類型如文件也不是類。然而,Python所有的數(shù)據(jù)類型都或多或少地帶有一些類似對象的語法。
對象是有單獨身份的,同一對象可以有多個名字與其聯(lián)系,這在其他語言中叫做別名。這樣做的好處乍一看并不明顯,而且對于非可變類型(數(shù)字、字符串、序表(tuple))等沒有什么差別。
但是別名句法對于包含可變對象如列表、字典及涉及程序外部物件如文件、窗口的程序有影響,這可以有利于程序編制。在引入類之前,我們必須講一講Python的作用域規(guī)則。類定義很好地利用了名字空間,需要了解Python如何處理作用域和名字空間才能充分理解類的使用。另外,作用域規(guī)則也是一個高級Python程序員必須掌握的知識。
因為別名有些類似指針:比如,傳遞一個對象變得容易,因為這只是傳遞了一個指針;如果一個函數(shù)修改了作為參數(shù)傳遞來的對象,修改結(jié)果可以傳遞回調(diào)用處。這樣就不必象Pascal那樣使用兩種參數(shù)傳遞機制。
名字空間是從名字到對象的映射。多數(shù)名字空間目前是用Python字典類型實現(xiàn)的,不過這一點一般是注意不到的,而且將來可能會改變。下面是名字空間的一些實例:Python中內(nèi)置的名字(如abs()等函數(shù),以及內(nèi)置的例外名);模塊中的全局名;函數(shù)調(diào)用中的局部變量名。
在某種意義上一個對象的所有屬性也構(gòu)成了一個名字空間。關(guān)于名字空間最重要的事要知道不同名字空間的名字沒有任何聯(lián)系;例如,兩個不同模塊可能都定義了一個叫“maximize ”的函數(shù)而不會引起混亂,因為模塊的用戶必須在函數(shù)名之前加上模塊名作為修飾。
另外,在Python應用程序中可以把任何一個在句點之后的名字稱為屬性,例如,在表達式z.real中,real是一個對象z的屬性。嚴格地說,對模塊中的名字的引用是屬性引用:在表達式modname.funcname 中,modname是一個模塊對象,funcname是它的一個屬性。
在這種情況下在模塊屬性與模塊定義的全局名字之間存在一個直接的映射:它們使用相同的名字空間!屬性可以是只讀的也可以是可寫的。在屬性可寫的時候,可以對屬性賦值。
名字空間與不同時刻創(chuàng)建,有不同的生存周期。包含Python內(nèi)置名字的名字空間當Python 解釋程序開始時被創(chuàng)建,而且不會被刪除。模塊的全局名字空間當模塊定義被讀入時創(chuàng)建,一般情況下模塊名字空間也一直存在到解釋程序退出。由解釋程序的最頂層調(diào)用執(zhí)行的語句。
不論是從一個腳本文件讀入的還是交互輸入的,都屬于一個叫做__main__的模塊,所以也存在于自己的全局名字空間之中。(內(nèi)置名字實際上也存在于一個模塊中,這個模塊叫做__builtin__ )。
函數(shù)的局部名字空間當函數(shù)被調(diào)用時創(chuàng)建,當函數(shù)返回或者產(chǎn)生了一個不能在函數(shù)內(nèi)部處理的例外時被刪除。(實際上,說是忘記了這個名字空間更符合實際發(fā)生的情況。)當然,遞歸調(diào)用在每次遞歸中有自己的局部名字空間。
一個作用域是Python應用程序中的一個文本區(qū)域,其中某個名字空間可以直接訪問?!爸苯釉L問” 這里指的是使用不加修飾的名字就直接找到名字空間中的對象,雖然作用域是靜態(tài)定義的,在使用時作用域是動態(tài)的。
在任何運行時刻,總是恰好有三個作用域在使用中(即恰好有三個名字空間是直接可訪問的):最內(nèi)層的作用域,最先被搜索,包含局部名字;中層的作用域,其次被搜索,包含當前模塊的全局名字;最外層的作用域最后被搜索,包含內(nèi)置名字。
【編輯推薦】