一. 什麼是python的反射機制?
python的反射機制,核心就是利用字符串去已存在的模塊中找到指定的屬性或方法,找到方法後自動執行,基於字符串的事件驅動!這也是python強大的自省能力!在Django的類視圖 和API開發中,路由的底層dispatch方法就是利用反射機制實現的,現在就來看看它的實現原理。
二.代碼搭建WEB框架:
1.首先我們先創建一個views.py模塊,用於實現web框架的視圖函數功能:
def index():
print('這是主頁面')
def registe():
print('這是註冊頁面')
def login():
print('這是登錄頁面')2.我們創建一個manage.py模塊,用於實現web框架的啟動頁面:
import views
def main():
url = input('請輸入要訪問頁面的url: ').strip()
if url == 'index':
views.index()
elif url == 'login':
views.login()
elif url == 'registe':
views.registe()
else:
print('404')
if __name__ == '__main__':
main()執行結果:

三. python中我們要注意的一個點:字符串與函數名調用問題
舉個例子:
def func():
print('func是函數的名字!')
a = "func"
print(a,type(a))a是一個字符串,我們可以用func()調用函數,但是不能用字符串去掉用函數func(),“func”()這樣是行不通的,但是有沒有一種辦法讓我們直接輸入的字符串去調用函數呢?python是動態語言,有很強的自省能力,自省就是面向對象的語言所寫的程序在運行時,能夠知道對象的類型。簡單一句就是,運行時能夠獲知對象的類型。這裡就要提到四個重要的方法:
getattr() hasattr() setattr () delattr()
1.getattr(__o,name,__default):獲得對象中的方法或變量的內存地址:
class Student():
def __init__(self,name):
self.name = name
def study(self):
print('%s正在學習'%self.name)
s1 = Student('小明')
a =getattr(s1,'name') #獲取name變量的內存地址
print(a) #輸出:小明
b = getattr(s1,'study') #獲取study的內存地址,從而可以用傳入的字符串去動態的調用函數
b() #調用study()方法 輸出:小明正在學習
c = getattr(s1,'age','no attribute')
print(c) #輸出:no attribute。因為age屬性在對象s1中沒有,本應該報錯,但是設置參數後找不到就報 no attribute
2.hasattr(__o,__name):判斷對象中是否有這個方法或變量,返回True 或False
class Student():
def __init__(self,name):
self.name = name
def study(self):
print('%s正在學習'%self.name)
s1 = Student('小明')
print(hasattr(s1,'study')) #輸出True s1實例對象有study()方法
print(hasattr(s1,'name')) #輸出True s1實例對象有name屬性
print(hasattr(s1,'eat')) #輸出False s1實例對象沒有eat屬性或方法
3. setattr(__object,__name,__value):為實例化對象動態添加屬性或方法
def study(self):
print('%s正在學習'%self.name)
class Student():
def __init__(self,name):
self.name = name
s1 = Student('小明')
setattr(s1,'study',study)
s1.study(s1) #動態給實例化對象添加方法
setattr(s1,'age',18)
print(s1.age) #動態給實例化對象添加屬性
四:反射機制
在我們上面搭建的Web框架中我們就會發現我們輸入的url就是views模塊中的方法名,如果我們直接用輸入得我字符串去調用對應的方法就會省好大的事,因為如果views.py模塊中有很多視圖函數的話,我們在manage.py中就要一個一個去判斷方法名,就很麻煩,所有用getattr()一行代碼就可以輕鬆搞定了!這也就是Django框架中類視圖 API接口底層dispatch()方法分發視圖函數的反射機制,代碼如下:
import views
def main():
url = input('請輸入要訪問的url: ').strip()
run = getattr(views, url)
run()
if __name__ == '__main__':
main()
輸入:index
輸出:這是主頁面
代碼優化:上面輸入中,若非法輸入或傳入views中沒有的視圖函數將報錯,這時我們可以用hasattr()去判斷views模塊中是否有傳入的視圖函數,hasattr()返回True,False:代碼如下
import views
def main():
url = input('請輸入要訪問的url: ').strip()
if hasattr(views,url):
run = getattr(views,url)
run()
else:
print('404')
if __name__ == '__main__':
main()
#這樣代碼就和原來的執行效果一模一樣了
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/252572.html
微信掃一掃
支付寶掃一掃