反射最初理解1
通過字串的形式,匯入模組2
我們前面講到的匯入模組,都是import 模組名稱 如:import mk 這種方式匯入的3
#!/usr/bin/env python # -*- coding:utf-8 -*- import mk #匯入mk模組 a = mk.dlu() #執行模組裡的函式 print(a) #執行函式 # 輸出 # 使用者登入 # None
如果模組名稱是字串型別,則無法匯入模組4
#!/usr/bin/env python # -*- coding:utf-8 -*- import "mk" #匯入mk模組 a = mk.dlu() #執行模組裡的函式 print(a) #執行函式 # 輸出 # File "H:/py/index.py", line 3 # import "mk" #匯入mk模組 # ^ # SyntaxError: invalid syntax
所以要想模組是字串型別匯入模組,有另外的一種方式
__import__()接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱5
使用方法1:模組名稱變數 = __import__("模組檔名稱")
使用方法2:如果模組在多層資料夾下:模組名稱變數 = __import__("模組路徑到模組檔名稱")
格式1:a = __import__("mk")
格式2:a = __import__("lib.ska.mk",fromlist=True)
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 a.dlu() #執行模組下的dlu()函式
如果模組在多層資料夾下
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("lib.ska.mk",fromlist=True) #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 b = a.dlu()#執行函式 print(b)#列印函式返回值 # 輸出 # 使用者登入 # None
通過字串的形式,去模組中尋找指定函式,或者全域性變數,並執行6
getattr()內建函式,到指定模組查詢指定函式或者指定全域性變數,並賦值給一個變數,如果找到的是函式賦值變數加()括號等於執行函式,如果找到的是全域性變數賦值變數就等於全域性變數值7
使用方法:賦值變數 = getattr(模組名稱, "字串形式函式名稱或變數名稱", 如果沒找到預設返回值)
格式:f = getattr(a,"dlu",None)
字串形式查詢函式
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 """通過字串的形式,去模組中尋找指定函式或者全域性變數,並執行""" f = getattr(a,"dlu",None) #getattr()內建函式,到指定模組查詢指定函式或者指定全域性變數,並賦值給一個變數,如果找到的是函式賦值變數加()括號等於執行函式,如果找到的是全域性變數賦值變數就等於全域性變數值 f()
字串形式查詢全域性變數
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 """通過字串的形式,去模組中尋找指定函式或者全域性變數,並執行""" f = getattr(a,"ASDF",None) #getattr()內建函式,到指定模組查詢指定函式或者指定全域性變數,並賦值給一個變數,如果找到的是函式賦值變數加()括號等於執行函式,如果找到的是全域性變數賦值變數就等於全域性變數值 print(f) #列印全域性變數
hasattr()內建函式,到指定模組查詢指定函式或者指定全域性變數,如果找到指定函式或者全域性變數返回True,否則返回False7
使用方法:賦值變數 = hasattr(模組名稱, "字串形式函式名稱或變數名稱")
格式:f = hasattr(a,"ASDF")
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 """內建函式,到指定模組查詢指定函式或者指定全域性變數""" f = hasattr(a,"ASDF") #hasattr()內建函式,到指定模組查詢指定函式或者指定全域性變數,如果找到指定函式或者全域性變數返回True,否則返回False print(f) #列印全域性變數 # 輸出 # True
setattr()內建函式,為模組在記憶體裡新增全域性變數或者函式8
使用方法:setattr(模組名稱, "字串形式函式名稱或變數名稱",全域性變數值或lambda表示式)
格式:setattr(a,"MF","8796")
為模組新增全域性變數
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 """內建函式,為模組在記憶體裡新增全域性變數或者函式""" setattr(a,"MF","8796") #setattr()內建函式,為模組在記憶體裡新增全域性變數或者函式 g = getattr(a,"MF",None) #到模組查詢到新增的MF全域性變數 print(g)#列印出新增的全域性變數 # 輸出 # 8796
為模組新增函式
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 """內建函式,為模組在記憶體裡新增全域性變數或者函式""" setattr(a,"f1",lambda b,c: b + c) #setattr()內建函式,為模組在記憶體裡新增全域性變數或者函式 f1 = getattr(a,"f1",None) #到模組查詢到新增的f1()函式 sfg = f1(1,2) #執行f1函式並傳值 print(sfg)#列印出函式的執行結果 # 輸出 # 3
delattr()內建函式,刪除模組在記憶體裡的函式或者全域性變數9
使用方法:delattr(模組名稱, "字串形式函式名稱或變數名稱")
格式:delattr(a,"dlu")
#!/usr/bin/env python # -*- coding:utf-8 -*- """字串型別的模組名,匯入mk模組""" a = __import__("mk") #接收字串型別的模組名稱,到程式目錄找到對應模組檔案匯入模組,賦值給一個變數,此變數等於重新定義模組名稱 """內建函式,刪除模組在記憶體裡的函式或者全域性變數""" b = hasattr(a,"dlu") #到指定模組查詢指定函式或者指定全域性變數,如果找到指定函式或者全域性變數返回True,否則返回False print(b) #列印返回值True,說明模組裡有dlu()函式 delattr(a,"dlu") #delattr()內建函式,刪除模組在記憶體裡的函式或者全域性變數 c = hasattr(a,"dlu") #到指定模組查詢指定函式或者指定全域性變數,如果找到指定函式或者全域性變數返回True,否則返回False print(c) #列印返回值False,說明模組記憶體裡已經刪除了這個函式 # 輸出 # True # False
反射總結:10
根據字串的形式去某個物件(模組)中尋找指定的函式或者全域性變數
根據字串的形式去某個物件(模組)中判斷指定的函式或者全域性變數是否存在
根據字串的形式去某個物件(模組)中設定指定的全域性變數或者函式
根據字串的形式去某個物件(模組)中刪除指定的函式或者全域性變數
反射的意義:根據字串的形式去物件(模組)中操作其成員11
基於反射模擬Web框架路由系統,根據使用者請求的url地址字尾,獲取字尾名稱,到指定模組查詢執行字尾對應的函式12
函式模組
#!/usr/bin/env python # -*- coding:utf8 -*- def shou(): print("首頁") def gong(): print("公司簡介") def chp(): print("產品展示") def liou(): print("留言板")
判斷頁面
"""根據使用者請求的url地址字尾,獲取字尾名稱,到指定模組執行字尾對應的函式""" url = "www.jxiou.com/liou" a = url.split("/") #根據/分割域名字串,返回列表 b = a[len(a)-1] #獲取列表的元素個數,在索引出域名字尾 from lib.ska import mk #匯入模組 if hasattr(mk,b): #判斷指定模組裡是否有字尾函式 c = getattr(mk,b) #如果有字尾函式,找到字尾函式賦值給一個變數 print(c()) #執行列印字尾函式 else: #如果模組裡沒有字尾函式,列印404 print("404")
基於反射模擬Web框架路由系統,根據使用者請求的url地址字尾,獲取字尾模組名稱和字尾函式名稱,查詢到指定模組下的指定函式並執行函式13
也就是根據url地址提供的模組名稱和函式名稱,查詢到對應的模組,和模組下對應的函式執行
函式模組1
#!/usr/bin/env python # -*- coding:utf8 -*- def shou(): print("首頁") def gong(): print("公司簡介") def chp(): print("產品展示") def liou(): print("留言板")
函式模組2
#!/usr/bin/env python # -*- coding:utf8 -*- def hout(): print("後臺首頁") def houd() print("後臺訂單")
判斷頁面1
#!/usr/bin/env python # -*- coding:utf-8 -*- """根據使用者請求的url地址字尾,獲取字尾模組名稱和字尾函式名稱,到指定模組執下找到指定函式並執行函式""" url = "www.jxiou.com/mk/gong" a = url.split("/") #根據/分割域名字串,返回列表 b = a[len(a)-1] #獲取字尾函式名 c = a[len(a)-2] #獲取字尾模組名 d = __import__("lib.ska.{}".format(c),fromlist=True) #根據url模組名稱找到模組 if hasattr(d,b): #判斷url函式在url模組裡是否存在 liou = getattr(d,b) #如果存在,找到函式賦值給一個變數 print(liou()) #執行列印變數 else: #如果不存在404 print("404") # 輸出 # 公司簡介 # None
判斷頁面2
#!/usr/bin/env python # -*- coding:utf-8 -*- """根據使用者請求的url地址字尾,獲取字尾模組名稱和字尾函式名稱,到指定模組執下找到指定函式並執行函式""" url = "www.jxiou.com/hou/houd" a = url.split("/") #根據/分割域名字串,返回列表 b = a[len(a)-1] #獲取字尾函式名 c = a[len(a)-2] #獲取字尾模組名 d = __import__("lib.ska.{}".format(c),fromlist=True) #根據url模組名稱找到模組 if hasattr(d,b): #判斷url函式在url模組裡是否存在 liou = getattr(d,b) #如果存在,找到函式賦值給一個變數 print(liou()) #執行列印變數 else: #如果不存在404 print("404") # 輸出 # 後臺訂單 # None