反射主要是指程序能夠訪問、檢測和修改其自己狀態或行爲的一種能力。在Python中最重要的4個方法以下所示:html
咱們先來定義一個類,以下所示:python
class Fruit: def __init__(self,name,color): self.name=name self.color=color def __str__(self): return f"Fruit is {self.name} color is {self.color}" def buy(self,price,totalWeight): return f"Fruit is {self.name},total price is {price*totalWeight}"
getattr主要用來獲取指定字符串名稱的對象屬性,其使用方法以下所示:微信
getattr(object, name:string[, default]) -> value
- name參數須要爲string類型,無論是判斷類屬性仍是類方法,其名稱均以字符串形式傳參
- 若是屬性存在,則返回其屬性值,不存在則分爲兩種狀況,一種是沒有default參數時,則直接報錯,如給定了default參數,對象沒有其屬性,則返回給定的default值
- 若是獲取的是類方法,則返回函數對象
之前面定義的Fruit類爲例app
# 實例化一個類 apple=Fruit("apple","red") # 利用反射獲取類屬性 print(getattr(apple,"name")) print(getattr(apple,"color")) # 利用反射獲取類方法 print(getattr(apple,"buy")) # 利用反射獲取不存在的屬性且有默認值 print(getattr(apple,"test","123")) # 利用反射獲取不存在的屬性且沒有默認值 - 報錯 print(getattr(apple,"test"))
輸出結果以下所示:函數
apple red <bound method Fruit.buy of <__main__.Fruit object at 0x000001E70B356288>> 123 Traceback (most recent call last): File "C:/Users/Surpass/Documents/PycharmProjects/SADCI/TempCode/reflectorSample.py", line 24, in <module> print(getattr(apple,"test")) AttributeError: 'Fruit' object has no attribute 'test'
setattr主要用於給對象添加一個類屬性,若是添加的屬性已經存在,則對其進行更新,不然則進行建立,其使用方法以下所示:測試
setattr(object, name:string, value)
name參數須要爲string類型,無論是判斷類屬性仍是類方法,其名稱均以字符串形式傳參ui
示例以下所示:code
# 實例化一個類 apple=Fruit("apple","red") # 爲實例添加一個類屬性,並設置其值 setattr(apple,"destination","china") print(f'第一次添加類屬性,其值爲(添加操做):{getattr(apple,"destination")}') setattr(apple,"destination","USA") print(f'第二次添加類屬性,其值爲(更新操做):{getattr(apple,"destination")}')
輸出結果以下所示:htm
第一次添加類屬性,其值爲(添加操做):china 第二次添加類屬性,其值爲(更新操做):USA
hasattr經常使用於判斷對象中是否存在其屬性或方法,經常使用用法以下所示:對象
hasattr(object, name:string) -> bool
name參數須要爲string類型,無論是判斷類屬性仍是類方法,其名稱均以字符串形式傳參
示例以下所示:
# 實例化一個類 apple=Fruit("apple","red") # 判斷屬性或方法是否存在 print(f'對象是否存在其屬性 name - {True if hasattr(apple,"name") else False }') print(f'對象是否存在其屬性 country - {True if hasattr(apple,"country") else False }') print(f'對象是否存在其方法 buy - {True if hasattr(apple,"buy") else False }')
輸出結果以下所示:
對象是否存在其屬性 name - True 對象是否存在其屬性 country - False 對象是否存在其方法 buy - True
delattr經常使用於刪除指定的屬性,但不能用於方法,經常使用用法以下所示:
delattr(object, name:string)
name參數須要爲string類型,無論是判斷類屬性仍是類方法,其名稱均以字符串形式傳參
示例以下所示:
# 實例化一個類 apple=Fruit("apple","red") delattr(apple,"name") # 判斷屬性或方法是否存在 print(f'對象是否存在其屬性 name - {True if hasattr(apple,"name") else False }') print(f'對象是否存在其屬性 country - {True if hasattr(apple,"country") else False }') print(f'對象是否存在其方法 buy - {True if hasattr(apple,"buy") else False }')
輸出結果以下所示:
對象是否存在其屬性 name - False 對象是否存在其屬性 country - False 對象是否存在其方法 buy - True
在平常使用,通常會進行判斷屬性是否存在,而後再調用獲取、添加和刪除方法
如下用一個簡單的示例來解釋,反射在實際的應用案例。如今有一個場景,就是根據傳入的不一樣的模塊名稱,調用不一樣的模塊所對應方法,代碼以下所示:
class ReflectSample: def moduleA(self): print("我是moduleA") def moduleB(self): print("我是moduleB") def moduleC(self): print("我是moduleC") def moduleD(self): print("我是moduleD")
while True: reflectSample=ReflectSample() choice=input("請輸入模塊名稱") if choice == "moduleA": reflectSample.moduleA() elif choice == "moduleB": reflectSample.moduleB() elif choice == "moduleC": reflectSample.moduleC() elif choice == "moduleD": reflectSample.moduleD() else: print("輸入的模塊不存在")
測試結果以下所示:
請輸入模塊名稱moduleA 我是moduleA 請輸入模塊名稱moduleD 我是moduleD 請輸入模塊名稱moduleF 輸入的模塊不存在
while True: reflectSample = ReflectSample() choice = input("請輸入模塊名稱") if hasattr(reflectSample,choice): func=getattr(reflectSample,choice) func() else: print("輸入的模塊不存在")
測試結果以下所示:
請輸入模塊名稱moduleA 我是moduleA 請輸入模塊名稱moduleD 我是moduleD 請輸入模塊名稱moduleF 輸入的模塊不存在
兩種方法一對比,天然就以爲方法二更簡潔,也更容易維護,更不用擔憂類中有不少個方法。
本文地址:http://www.javashuo.com/article/p-sosyssjy-bq.html
本文同步在微信訂閱號上發佈,如各位小夥伴們喜歡個人文章,也能夠關注個人微信訂閱號:woaitest,或掃描下面的二維碼添加關注: