python中的反射和自省
本文主要介紹python中的反射和自省,以及該機制的簡單應用
熟悉JAVA的程式設計師,一定經常和Class.forName打交道。即使不是經常親自呼叫這個方法,但是在很多框架中(Spring,eclipse plugin機制)都依賴於JAVA的發射和自省能力。而在python中,也同樣有著強大的反射和自省能力,本文將做簡單的介紹。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
首先看一下自省,介紹一下幾個重要的函式:
dir函式,傳入的引數是物件,返回該物件的所有屬性和函式列表:
如:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
可以看到,string物件的所有函式,屬性都列舉出來了。
getattr方法,傳入引數是物件和該物件的函式或者屬性的名字,返回物件的函式或者屬性例項,如下:
callable方法,如果傳入的引數是可以呼叫的函式,則返回true,否則返回false。
下面這段程式碼列出物件所有函式:
methodList = [method for method in dir(object) if callable(getattr(object,method))]
比如檢視string的所有函式:
接下來,看看python的是如何體現反射的。
globals()
這個函式返回一個map,這個map的key是全域性範圍內物件的名字,value是該物件的例項。
在不匯入任何module下,執行globals()的結果如下:
在匯入sys後,可以發現,globals()返回的map中,多了sys module:
在匯入sgmllib,如下:
如果匯入類後,在map中,可以找到類。
所以,只要將class的名字最為key,即可得到class。如下:
而如果要例項化一個物件,可以如下:
這樣,實現了類似
所以,我在介紹一種可以動態匯入的方法。
首先,介紹一個函式 __import__, 這個函式傳入的引數是module的名字,返回這個module,然後,在結合之前介紹過的getattr,於是,我們可以寫出下面兩句程式碼,實現物件的自省。
由此可見,python提供的反射和自省機制是十分便捷的。這也方便了很多操作。比如,如下這段程式碼,將匯入指令碼檔案所在資料夾下的所有測試檔案(以test結尾的指令碼檔案0,並進行測試。
程式碼出自dive in python(這本書寫的很好),比較容易理解,不做詳細介紹了。主要是先獲得目錄,然後過濾出符合條件的指令碼檔案,去掉字尾名,作為模組載入。