在Python中,所有以__雙下劃線包起來的方法,都統稱爲"魔術方法"
在之前的接觸中,我們有見過__init__,當然也是很常見的,除了__init__,我們也要了解下__new__,__del__,
__getattribute__,__getattr__,__setattr__,__delattr__
class Stu:
def __init__(self, stu_no, stu_name, stu_sex):
"""
:param stu_no: --->str
:param stu_name: --->str
:param stu_sex: ---->str
"""
self.stu_no = stu_no
self.stu_name = stu_name
self.stu_sex = stu_sex
if __name__ == "__main__":
stu_01 = Stu("Stu_001", "小明", "女")
print(stu_01.weight)
1. 類的實例化時涉及的魔法函數:
1) __init__,__new__ : 】
在對象進行實例化時,通過__init__講參數傳給通過__new__而創建的類的實例,進而實現類的實例化,所以類的實例化時,
__init__不一定會被調用,但是__new__先是會被首先掉用的
2) __del__: 在對象的生命週期結束時, __del__
會被調用,類似於一個對象不用了之後進行回收了
2. 屬性訪問或者修改時所涉及的幾個魔法函數:
1) __getattribute__:訪問屬性時,就會調用該函數一次,無論屬性存不存在
通過截圖可知:訪問屬性時,就會調用該函數一次,無論屬性存不存在,但是返回的值卻不對,那如何處理纔會得到我們預期中想要的結果呢? 那麼我們就需要對該函數進行重寫,如下所示:
def __getattribute__(self, item):
# 當對象訪問屬性時,會自動觸發這個方法,有這個方法來決定返回的屬性值
try:
return super().__getattribute__(item) # 重寫父類__getattribute__()方法
except AttributeError as msg: # 訪問屬性出現異常時,返回None
print(f"{item}屬性不存在")
return None
這是代碼運行,運行結果就是:
2)_getattr__(self, item): 跟__getattribute__(self, item)函數類似的功能的魔法函數,只不過該函數相當於是__getattribute__(self, item)的優化版,無需進行try...except處理
def __getattr__(self, item):
# 當訪問屬性時,屬性不存在時,也不會報錯,自動返回None,當訪問屬性存在時,返回屬性值,
# 相當於__getattribute__的自帶捕獲異常處理
print("調用__getattr__(self, item)魔法函數")
代碼運行結果:
3) __setattr__(self, key, value) :設置屬性時,包括:init初始化傳參,對象新增屬性,都調用該魔術方式
通過截圖看出,設置屬性時,包括:init初始化傳參,對象新增屬性,都調用該魔術方式,但是最終再想要訪問新建的屬性時,卻報錯,此時我們需要怎麼處理呢? 重寫父類Object __setattr__(self, key, value)
def __setattr__(self, key, value): # 設置屬性時會被觸發
print("設置屬性時會被觸發_setattr__函數")
super().__setattr__(key, value)
運行結果如下:
4) __delattr__(self, item) : 刪除屬性時會被觸發
def __delattr__(self, item): # 刪除屬性時會被觸發
print(f"這個是__delattr__,正在刪除{item}屬性")
如果說,不允許某些屬性被刪除,那麼可以進行如下處理:
def __delattr__(self, item): # 刪除屬性時會被觸發
if item not in ["stu_no", "stu_name", "stu_sex"]: # 則name2屬性不允許刪除
print(f"這個是__delattr__,正在刪除{item}屬性")
super().__delattr__(item)
else:
print(f"{item}屬性不允許刪除")
運行結果: