本篇是 Python 系列教程第 14 篇,更多內容敬請訪問我的 Python 合集
在Python中,“反射”通常指的是根據字串查詢並執行相關的類、方法或者屬性的能力。Python提供了幾個內建函式和語法特性來支援這種能力,比如getattr()
, setattr()
, hasattr()
, delattr()
以及dir()
等。這些功能使得程式可以在執行時動態地獲取和設定物件的屬性和方法,從而增強程式碼的靈活性。
前面函式那一篇粗略的介紹了Python內建函式,也講到了getattr()
等內建函式,下面再系統具體的介紹一下。
常見的反射相關函式
-
getattr(object, name[, default])
:- 作用:從給定的物件中獲取指定名字的屬性值。
- 如果屬性存在,則返回該屬性值;否則,如果提供了預設值,則返回預設值;如果沒有提供預設值且屬性不存在,則丟擲
AttributeError
。
-
setattr(object, name, value)
:- 作用:為給定的物件設定指定名字的屬性值。
- 如果物件不允許賦值,則丟擲
AttributeError
。
-
hasattr(object, name)
:- 作用:檢查給定的物件是否具有指定名字的屬性。
- 返回布林值。
-
delattr(object, name)
:- 作用:刪除給定物件的指定屬性。
- 如果屬性不存在,則丟擲
AttributeError
。
-
dir(object)
:- 作用:返回一個包含物件的所有屬性名的列表。
- 如果物件定義了
__dir__()
方法,則優先使用該方法;否則使用預設方式。
示例
下面是一些使用這些反射函式的例子:
class MyClass:
def __init__(self):
self.x = 10
self.y = 20
def greet(self):
return "Hello from MyClass!"
# 建立一個MyClass的例項
my_instance = MyClass()
# 使用反射獲取屬性值
x_value = getattr(my_instance, 'x')
print(f"x 的值是: {x_value}") # 輸出: x 的值是: 10
# 設定一個新的屬性值
setattr(my_instance, 'z', 30)
# 檢查是否有某個屬性
has_z = hasattr(my_instance, 'z')
print(f"my_instance 是否有屬性 z? {has_z}") # 輸出: my_instance 是否有屬性 z? True
# 刪除屬性
delattr(my_instance, 'z')
# 列出所有屬性
all_attributes = dir(my_instance)
print("所有屬性:", all_attributes)
使用反射的好處
- 動態性:反射使得程式能夠在執行時動態地響應變化,例如,根據不同的輸入或配置載入不同的類或方法。
- 程式碼重用:透過反射,可以編寫通用的函式來處理不同型別的物件,只要這些物件遵循一定的介面或約定。
- 擴充套件性:反射可以方便地擴充套件程式的功能,而無需修改現有程式碼。
然而,過度使用反射可能會導致程式碼難以理解和維護,因為它打破了靜態型別語言的一些預期。因此,在使用反射時要謹慎,並確保它確實能帶來便利性和靈活性。