Python反射機(jī)制案例超詳細(xì)講解
一、導(dǎo)包案例
我們導(dǎo)入第三方庫,可以使用import。那我們現(xiàn)在有一個需求,我需要動態(tài)輸入一個模塊名,然后導(dǎo)入,這應(yīng)該怎么做呢?
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "反射.py"
__time__ = "2022/8/10 13:11"
# package = input("請輸入您想導(dǎo)入的庫:")
package = "requests" # 導(dǎo)入requests庫
req = __import__(package) # 通過字符串的方式導(dǎo)入庫
resp = req.get("https://www.baidu.com") # 調(diào)用庫中的函數(shù)
print(resp)上面我們實現(xiàn)了動態(tài)輸入模塊名,從而使我們能夠輸入模塊名并且執(zhí)行里面的函數(shù)。但是上面有一個缺點,那就是執(zhí)行的函數(shù)被固定了。那么,我們能不能改進(jìn)一下,動態(tài)輸入函數(shù)名,并且來執(zhí)行呢?
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "反射.py"
__time__ = "2022/8/10 13:11"
# package = input("請輸入要調(diào)用的模塊:")
package = "demo01" # 導(dǎo)入第三方模塊
req = __import__(package) # 導(dǎo)入庫
# func = input("請輸入要執(zhí)行的函數(shù):")
func = "func" # 要執(zhí)行的函數(shù)
_ = getattr(req, func, None) # 獲取名為func的函數(shù),如果沒有返回None
_() # 調(diào)用函數(shù)
面我們就實現(xiàn)了,動態(tài)導(dǎo)入一個模塊,并且動態(tài)輸入函數(shù)名然后執(zhí)行相應(yīng)功能。
當(dāng)然,上面還存在一點點小問題:那就是我的模塊名有可能不是在本級目錄中存放著。有可能是如下圖存放方式:

那么,我們應(yīng)該如何解決呢?這時可以添加一個參數(shù),fromlist:
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "反射.py"
__time__ = "2022/8/10 13:11"
# package = input("請輸入要調(diào)用的模塊:")
package = "test.demo01" # 級聯(lián)導(dǎo)入
req = __import__(package, fromlist=True) # 導(dǎo)入庫,注意要添加fromlist參數(shù)
# func = input("請輸入要執(zhí)行的函數(shù):")
func = "func" # 要執(zhí)行的函數(shù)
_ = getattr(req, func, None) # 獲取名為func的函數(shù),如果沒有返回None
_() # 調(diào)用函數(shù)
二、基礎(chǔ)知識
1、是什么
什么是反射?
- 有時我們要訪問某個變量或是方法時并不知道到底有沒有這個變量或方法,所以就要做些判斷。判斷是否存在字符串對應(yīng)的變量及方法。
- 我們知道訪問變量時是不能加引號的,否則會被當(dāng)成字符串處理。如果要通過字符串找到對應(yīng)的變量,那該怎么辦呢?
反射就是用于解決上面兩個問題而產(chǎn)生的,所謂反射,按我的理解就是反過來告訴我字符串是什么,是變量或者是方法
python的反射,它的核心本質(zhì)其實就是利用字符串的形式去對象(模塊)中操作(查找/獲取/刪除/添加)成員,一種基于字符串的事件驅(qū)動!
python中訪問類或?qū)ο蟮某蓡T有三種方法:
如下所示 obj 為對象 var為變量 func為函數(shù)
1、obj.var 或 obj.func()
2、obj.__dict__['var']
3、getattr(obj,'var')
反射的方法:
hasattr(obj,name_str): 判斷objec是否有name_str這個方法或者屬性
getattr(obj,name_str): 獲取object對象中與name_str同名的方法或者函數(shù),有則返回地址
setattr(obj,name_str,value): 為object對象設(shè)置一個以name_str為名的value方法或者屬性
delattr(obj,name_str): 刪除object對象中的name_str方法或者屬性
2、怎么用
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "反射.py"
__time__ = "2022/8/10 13:11"
def func(self):
print("hello world", self)
# 首先,我們創(chuàng)建一個學(xué)生類,這個學(xué)生類沒有綁定任何屬性和方法
class Stu:
pass
s = Stu()
# 我們可以使用反射機(jī)制,對類成員進(jìn)行方法和屬性的綁定,如我們創(chuàng)建一個成員方法
if hasattr(s, "func"): # 如果有這個函數(shù),進(jìn)行刪除,重新綁定
delattr(s, "func")
setattr(s, "func", func) # 進(jìn)行函數(shù)的綁定,注意,給Stu綁定和給s綁定的效果是不一樣的
_ = getattr(s, "func", None) # 對這個函數(shù)進(jìn)行查找
_(s) # 調(diào)用函數(shù),等于是調(diào)用了成員函數(shù),需要手動傳遞self三、使用案例
python反射機(jī)制在路由中比較常見
import requests
class Http(object):
def get(self, url):
"""get請求"""
res = requests.get(url)
response = res.text
return response
def post(self, url):
"""post請求"""
res = requests.post(url)
response = res.text
return response
# 使用反射后
url = "https://www.baidu.com"
method = input("請求方法>>>:")
h = Http()
if hasattr(h, method):
func = getattr(h, method)
res = func(url)
"""
如果給通過類獲取這個方法,則調(diào)用時需要傳入類成員
func = getattr(Http, method)
res = func(h, url)
"""
print(res)
else:
print("你的請求方式有誤...")到此這篇關(guān)于Python反射機(jī)制案例超詳細(xì)講解的文章就介紹到這了,更多相關(guān)Python反射機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
flask 使用 flask_apscheduler 做定時循環(huán)任務(wù)的實現(xiàn)
這篇文章主要介紹了flask 使用 flask_apscheduler 做定時循環(huán)任務(wù)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Pytorch 實現(xiàn)凍結(jié)指定卷積層的參數(shù)
今天小編就為大家分享一篇Pytorch 實現(xiàn)凍結(jié)指定卷積層的參數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Python os.mkdir()與os.makedirs()的使用區(qū)別
這篇文章主要介紹了Python os.mkdir()與os.makedirs()的使用區(qū)別,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
django filter過濾器實現(xiàn)顯示某個類型指定字段不同值方式
這篇文章主要介紹了django filter過濾器實現(xiàn)顯示某個類型指定字段不同值方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
Django 狀態(tài)保持搭配與存儲的實現(xiàn)
本文主要介紹了Django 狀態(tài)保持搭配與存儲的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06

