什麼是反射?
1、有時我們要訪問某個變數或是方法時並不知道到底有沒有這個變數或方法,所以就要做些判斷。判斷是否存在字串對應的變數及方法。
2、我們知道訪問變數時是不能加引號的,否則會被當成字串處理。如果要通過字串找到對應的變數,那該怎麼辦呢
反射就是用於解決上面兩個問題而產生的,所謂反射,按我的理解就是反過來告訴我字串是什麼,是變數or方法
python的反射,它的核心本質其實就是利用字串的形式去物件(模組)中操作(查詢/獲取/刪除/新增)成員,一種基於字串的事件驅動!
還是很難理解?
舉個例子:
比如老王往自己的銀行卡裡面存了一筆錢。
這個數字老王是知道的。如果老王如實交代還好,如果不如實交代。他老婆是不知道的。
如果他老婆想知道這筆錢的數目。他老婆需要拿著這張卡,去銀行查流水。
這個就相當是兩條路徑:
老王,往卡裡面,存5000,這個是正向過程。
老王老婆,拿老王(物件)的卡(模組),去查流水(操作),得出老王存了5000。這個是逆向的過程。就像鏡子的反射。
一般正向的就是,當事人操作
反向的就是非當事人,對當事人的行為推理操作
反射就是用字串資料型別的變數名去訪問變數.
python中訪問類或物件的成員有三種方法:
如下所示 obj 為物件 var為變數 func為函式
1、obj.var 或 obj.func()
2、obj.__dict__['var']
3、getattr(obj,'var')
反射當前模組
還可以匯入其他模組,利用反射查詢該模組是否存在某種方法.
import sys
def s1():
print('s1')
def s2():
print ('s2')
this_module = sys.modules['__main__'] #__main__表示當前檔案
print(hasattr(this_module, 's1')) #判斷's1'是否在當前檔案的方法名中
getattr(this_module, 's2')() #取出
import和__import__()
import作用:
匯入/引入乙個python標準模組,其中包括.py檔案、帶有init.py檔案的目錄;
__import__作用:
同import語句同樣的功能,但__import__是乙個函式,並且只接收字串作為引數
函式功能用於動態的匯入模組,主要用於反射或者延遲載入模組。
__import__(module)相當於import module
__import__(package.module)相當於from package import name,如果fromlist不傳入值,則返回package對應的模組,如果fromlist傳入值,則返回package.module對應的模組。
我動態輸入乙個模組名,可以隨時訪問到匯入模組中的方法或者變數.
imp = input("請輸入模組:")
dd = __import__(imp)# 等價於import imp
inp_func = input("請輸入要執行的函式:")
f = getattr(dd,inp_func,none)
#作用:從匯入模組中找到你需要呼叫的函式inp_func,然後
返回乙個該函式的引用.沒有找到就煩會none
f() # 執行該函式
上面還存在一點點小問題:那就是我的模組名有可能不是在本級目錄中存放著
dd = __import__("lib.text.commons") #這樣僅僅匯入了lib模組
dd = __import__("lib.text.commons",fromlist = true) #改用這種方式就能匯入成功
# 等價於import config
inp_func = input("請輸入要執行的函式:")
f = getattr(dd,inp_func)
f()
反射:
1. getattr()函式是python自省的核心函式,具體使用大體如下:class a: def __init__(self):
self.name = 'zhangjing'#self.age='24'def method(self):
print"method print"
instance = a()
print getattr(instance , 'name, 'not find') #如果instance 物件中有屬性name則列印self.name的值,否則列印'not find'
print getattr(instance , 'age', 'not find') #如果instance 物件中有屬性age則列印self.age的值,否則列印'not find'
print getattr(a, 'method', 'default') #如果有方法method,否則列印其位址,否則列印default
print getattr(a, 'method', 'default')() #如果有方法method,執行函式並列印none否則列印default
2. hasattr(object, name)
說明:判斷物件object是否包含名為name的特性(hasattr是通過呼叫getattr(ojbect, name)是否丟擲異常來實現的)
3. setattr(object, name, value)
這是相對應的getattr()。引數是乙個物件,乙個字串和乙個任意值。字串可能會列出乙個現有的屬性或乙個新的屬性。這個函式將值賦給屬性的。該物件允許它提供。例如,setattr(x,「foobar」,123)相當於x.foobar = 123。
4. delattr(object, name)
與setattr()相關的一組函式。引數是由乙個物件(記住python中一切皆是物件)和乙個字串組成的。string引數必須是物件屬性名之一。該函式刪除該obj的乙個由string指定的屬性。delattr(x, 'foobar')=del x.foobar
例項:基於反射機制模擬web框架路由
需求:比如我們輸入:返回f1的結果。
# 動態匯入模組,並執行其中函式url = input("url: ")
target_module, target_func = url.split('/')
m = __import__('lib.'+target_module, fromlist=true)
inp = url.split("/")[-1] # 分割url,並取出url最後乙個字串
if hasattr(m,target_func): # 判斷在commons模組中是否存在inp這個字串
target_func = getattr(m,target_func) # 獲取inp的引用
target_func() # 執行
else:
print("404")
這下搞明白了麼? python中的反射
反射 對於初學python可能較難理解,但反射是非常有用。試想一下,當別的程式傳入給你寫的這段 乙個變數 var math 這個變數是乙個字串,這個字串是乙個模組或者乙個模組下的某個方法,你需要通過變數來匯入此模組或者方法,如何匯入此模組或方法呢,如果直接執行 import var是會出錯的,因為v...
Python中的反射
反射在python中我們可以簡單的理解為通過字串來操作物件的屬性和方法。python中有4個與反射相關的方法 class animal object def init self,name,age self.name name self.age age an animal dog 2 判斷an物件是否...
python中的反射
反射 對於初學python可能較難理解,但反射是非常有用。試想一下,當別的程式傳入給你寫的這段 乙個變數 var math 這個變數是乙個字串,這個字串是乙個模組或者乙個模組下的某個方法,你需要通過變數來匯入此模組或者方法,如何匯入此模組或方法呢,如果直接執行 import var是會出錯的,因為v...