標籤:百度 其他 研究 代碼 hdf env ase usr body
斷斷續續從年前到現在學了物件導向一個月了,之前學反射的時候,只是都是看下代碼,理解就可以了,今天在代碼的時候還是不太得心應手,於是百度各種,終於明白了,寫此部落格,供自省。
反射1 什麼是反射
反射的概念是由Smith在1982年首次提出的,主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了電腦科學領域關於應用反射性的研究。它首先被程式語言的設計領域所採用,並在Lisp和物件導向方面取得了成績。
2 python物件導向中的反射:通過字串的形式操作對象相關的屬性。python中的一切事物都是對象(都可以使用反射)
四個可以實現自省的函數 下列方法適用於類和對象(一切皆對象,類本身也是一個對象)
看了定義,還是只是瞭解一下,不貼代碼都是刷流氓,直接上代碼。
# test.pyimport sysdef fn(): print(‘hello world‘)func_name = fn.__name__fn_obj = getattr(sys.modules[__name__], func_name) # 根據函數名(func_name),獲得函數對象fn_obj()
運行結果是:
hello world
先大致看一下思路,
1. 首先定義了一個fn的函數
2. 通過擷取當前__name__的值 來反射
估計你也是看的雲裡霧裡。接下來我一一解釋。
拋磚引玉
對於__name__大家不知道理解不,上代碼。
#!/usr/bin/env pythondef test(): print(‘hello world.‘) print("__name__ = ",__name__)if __name__ == ‘__main__‘: test()[email protected]:~$ cat test2.py import testtest.test()
運行
[email protected]:~$ python3 test.py hello world.__name__ = __main__[email protected]:~$ python3 test2.py hello world.__name__ = test
從上可以看出,直接運行test的時候__name__就是等於字串‘__main__’,要是被其他檔案匯入此時__name__就是等於模組名字。
總結:
當模組不是匯入,而是直接運行,那麼__name__的值就是__main__。理解__name__了吧。
知識點:
sys.modules是一個全域字典,該字典是python啟動後就載入在記憶體中。每當程式員匯入新的模組,sys.modules都將記錄這些模組。字典sys.modules對於載入模組起到了緩衝的作用。當某個模組第一次匯入,字典sys.modules將自動記錄該模組。當第二次再匯入該模組時,python會直接到字典中尋找,從而加快了程式啟動並執行速度。
既然懂了__name__,接下來我們繼續最初的代碼一一分析。
自省的函數 下列方法適用於類和對象(一切皆對象,類本身也是一個對象),先看其中兩個。
hasattr(object,name)
判斷object中有沒有一個name字串對應的方法或屬性
getattr(object, name, default=None)
def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, ‘y‘) is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn‘t exist; without it, an exception is raised in that case. """ pass
# test.pyimport sysdef fn(): print(‘hello world‘)func_name = fn.__name__ # fn_obj = getattr(sys.modules[__name__], func_name) # 根據函數名(func_name),獲得函數對象fn_obj()
分析
1. 此時等於 func_name 等於 fn,2. __name__ 等於 __main__3. sys.modules[__name__] 等於 sys.modules[test.py] #這個可能說不太妥當4. getattr(sys.modules[__name__], func_name) 也就是sys.modules[__name__] 中取fn方法對象。
5. fn_obj() 表示 sys.modules[__name__] 中取fn方法實現也就是執行輸出
此時應該理解最初的代碼了吧
知識點 - python 反射