Python 反射

首先說說反射是什么?反射是可以以字符串的形式動態(tài)調(diào)用函數(shù)的過程。

當(dāng)然反射不只是字符串的函數(shù)執(zhí)行,她和exec和eval不同,反射還可以動態(tài)調(diào)用函數(shù)

eg:如def fun(): print 'a'? 我們調(diào)用的時候應(yīng)該是fun(),如果我們定以一個字符串b =fun,我們在以b()調(diào)用函數(shù)則會報錯,所以函數(shù)調(diào)用的時候不能是字符串

但是有時候我們遇到的問題如果能以字符串讀取 并且可以動態(tài)調(diào)用 就會比較方便

eg:我要定義一個網(wǎng)頁的功能,假定下面的這些函數(shù)是在commons模塊里面

def login():

? ? ? print("這是一個登陸頁面!")

def logout():

? ? print("這是一個退出頁面!")

def home():

? ? print("這是網(wǎng)站主頁面!"

這樣我們輸入網(wǎng)址,根據(jù)split分割的網(wǎng)址,如果網(wǎng)址第二項是login就調(diào)用第一個函數(shù),是logout就調(diào)用第二個函數(shù)等等,我們可以使用if

import commons

def run():

? ? ? inp = input("請輸入您想訪問頁面的url: ").strip()

? if inp == "login":

? ? commons.login()

? elif inp == "logout":

? ? commons.logout()

? elif inp == "home":

? ? commons.home()

? else:

? ? print("404")

if __name__ == '__main__':

? run()

但是如果我們的類型有100個甚至1000個的時候呢,這樣如果前面我們還是if...這樣我們要寫100甚至1000個,那如果這個時候我們的函數(shù)可以動態(tài)讀取字符串進行調(diào)用的話,我們是不是可以根據(jù)倒數(shù)第二項返回的字符串立即調(diào)用函數(shù),不用再每個 類型使用一次if,例如:

import commons

def run():

? ? inp = input("請輸入您想訪問頁面的url: ").strip()

? func = getattr(commons,inp)#getattr尋找commons里面的inp函數(shù),把字符串形式變成函數(shù)類型

? func()#函數(shù)執(zhí)行

if __name__ == '__main__':

? run()

這樣是不是簡單明了,直接用一個動態(tài)過程進行了函數(shù)調(diào)用

同時,我們也可以使用_import_動態(tài)調(diào)用模塊,其實本身我們直接用import的 時候,里面本質(zhì)的過程就是_import_(),具體使用過程如下:

def run():

? inp = input("請輸入您想訪問頁面的url: ").strip()

? modules, func = inp.split("/")

? obj = __import__(modules)#查找與字符串相同的模塊

? if hasattr(obj, func):#判斷對象中是否有func,返回bool布爾值

? ? func = getattr(obj, func)

? ? func()

? else:

? ? print("404")

if __name__ == '__main__':

? run()

另外需要 注意:如果存在模塊和真實的函數(shù)調(diào)用存在出入,并且有跡可循,例如全是w.函數(shù)? 這時我們直接用"w."+modules是不可以的,我們必須這樣使用? __import__("lib." + modules, fromlist=True) 必須 加上fromlist參數(shù),不然_import_就只會讀取點號之前的字符串去模塊中進行查找

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。