本文主要介紹python中的反射和自省,以及該機(jī)制的簡(jiǎn)單應(yīng)用 熟悉JAVA的程序員,一定經(jīng)常和Class.forName打交道。即使不是經(jīng)常親自調(diào)用這個(gè)方法,但是在很多框架中(Spring,eclipse plugin機(jī)制)都依賴于JAVA的發(fā)射和自省能力。而在python中,也同樣有著強(qiáng)大的反射和自省能力,本文將做簡(jiǎn)單的介紹。 首先看一下自省,介紹一下幾個(gè)重要的函數(shù): dir函數(shù),傳入的參數(shù)是對(duì)象,返回該對(duì)象的所有屬性和函數(shù)列表: 如:
可以看到,string對(duì)象的所有函數(shù),屬性都列舉出來了。 getattr方法,傳入?yún)?shù)是對(duì)象和該對(duì)象的函數(shù)或者屬性的名字,返回對(duì)象的函數(shù)或者屬性實(shí)例,如下:
callable方法,如果傳入的參數(shù)是可以調(diào)用的函數(shù),則返回true,否則返回false。
下面這段代碼列出對(duì)象所有函數(shù): methodList = [method for method in dir(object) if callable(getattr(object,method))] 比如查看string的所有函數(shù):
接下來,看看python的是如何體現(xiàn)反射的。 globals() 這個(gè)函數(shù)返回一個(gè)map,這個(gè)map的key是全局范圍內(nèi)對(duì)象的名字,value是該對(duì)象的實(shí)例。 在不導(dǎo)入任何module下,執(zhí)行globals()的結(jié)果如下: 在導(dǎo)入sys后,可以發(fā)現(xiàn),globals()返回的map中,多了sys module:
在導(dǎo)入sgmllib,如下:
如果導(dǎo)入類后,在map中,可以找到類。
所以,只要將class的名字最為key,即可得到class。如下:
而如果要實(shí)例化一個(gè)對(duì)象,可以如下:
這樣,實(shí)現(xiàn)了類似java中,Class.forName().newInstance()的功能。但是,在使用globals函數(shù)之前,還需要導(dǎo)入相應(yīng)的類,如果不導(dǎo)入,而直接使用globals[‘...’]查找這個(gè)類,則會(huì)拋出異常。 所以,我在介紹一種可以動(dòng)態(tài)導(dǎo)入的方法。 首先,介紹一個(gè)函數(shù) __import__, 這個(gè)函數(shù)傳入的參數(shù)是module的名字,返回這個(gè)module,然后,在結(jié)合之前介紹過的getattr,于是,我們可以寫出下面兩句代碼,實(shí)現(xiàn)對(duì)象的自省。
由此可見,python提供的反射和自省機(jī)制是十分便捷的。這也方便了很多操作。比如,如下這段代碼,將導(dǎo)入腳本文件所在文件夾下的所有測(cè)試文件(以test結(jié)尾的腳本文件0,并進(jìn)行測(cè)試。
代碼出自dive in python(這本書寫的很好),比較容易理解,不做詳細(xì)介紹了。主要是先獲得目錄,然后過濾出符合條件的腳本文件,去掉后綴名,作為模塊加載。 |
|