第四十九,反射基本介紹

weixin_34293059發表於2016-09-13

反射最初理解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

 

相關文章