python魔法方法之__setattr__()
前言:
python提供了諸多的魔法方法,其中__setattr__()方法主要用于類實(shí)例進(jìn)行屬性賦值,其定義在Object類官方提供的說(shuō)明如下:
Called when an attribute assignment is attempted.
This is called instead of the normal mechanism (i.e. store the value in the instance dictionary).
name is the attribute name, value is the value to be assigned to it.
簡(jiǎn)單的說(shuō),__setattr__()在屬性賦值時(shí)被調(diào)用,并且將值存儲(chǔ)到實(shí)例字典中,這個(gè)字典應(yīng)該是self的__dict__屬性。即:在類實(shí)例的每個(gè)屬性進(jìn)行賦值時(shí),都會(huì)首先調(diào)用__setattr__()方法,并在__setattr__()方法中將屬性名和屬性值添加到類實(shí)例的__dict__屬性中。
1、實(shí)例屬性管理__dict__
下面的測(cè)試代碼中定義了三個(gè)實(shí)例屬性,每個(gè)實(shí)例屬性注冊(cè)后都print()
此時(shí)的__dict__
,
代碼如下:
class AnotherFun: ? ? def __init__(self): ? ? ? ? self.name = "Liu" ? ? ? ? print(self.__dict__) ? ? ? ? self.age = 12 ? ? ? ? print(self.__dict__) ? ? ? ? self.male = True ? ? ? ? print(self.__dict__) another_fun = AnotherFun()
得到的結(jié)果顯示出,每次實(shí)例屬性賦值時(shí),都會(huì)將屬性名和對(duì)應(yīng)值存儲(chǔ)到__dict__字典中:
{'name': 'Liu'} {'name': 'Liu', 'age': 12} {'name': 'Liu', 'age': 12, 'male': True}
2、__setattr__()與__dict__
由于每次類實(shí)例進(jìn)行屬性賦值時(shí)都會(huì)調(diào)用__setattr__()
,所以可以重載__setattr__()方法,來(lái)動(dòng)態(tài)的觀察每次實(shí)例屬性賦值時(shí)__dict__()的變化。下面的Fun類重載了__setattr__()方法,并且將實(shí)例的屬性和屬性值作為_(kāi)_dict__的鍵-值對(duì):
class Fun: ? ? def __init__(self): ? ? ? ? self.name = "Liu" ? ? ? ? self.age = 12 ? ? ? ? self.male = True ? ? ? ?? ? ? def __setattr__(self, key, value): ? ? ? ? print("*"*50) ? ? ? ? print("setting:{}, ?with:{}".format(key[], value)) ? ? ? ? print("current __dict__ : {}".format(self.__dict__)) ? ? ? ? # 屬性注冊(cè) ? ? ? ? self.__dict__[key] = value fun = Fun() ? ?
通過(guò)在__setattr__()中將屬性名作為key,并將屬性值作為value,添加到了__dict__中,得到的結(jié)果如下:
**************************************************
setting:name, with:Liu
current __dict__ : {}
**************************************************
setting:age, with:12
current __dict__ : {'name': 'Liu'}
**************************************************
setting:male, with:True
current __dict__ : {'name': 'Liu', 'age': 12}
可以看出,__init__()中三個(gè)屬性賦值時(shí),每次都會(huì)調(diào)用一次__setattr__()
函數(shù)。
3、重載__setattr__()必須謹(jǐn)慎
由于__setattr__()
負(fù)責(zé)在__dict__中對(duì)屬性進(jìn)行注冊(cè),所以自己在重載時(shí)必須進(jìn)行屬性注冊(cè)過(guò)程,下面是__setattr__()不進(jìn)行屬性注冊(cè)的例子:
class NotFun: ? ? def __init__(self): ? ? ? ? self.name = "Liu" ? ? ? ? self.age = 12 ? ? ? ? self.male = True ? ?? ? ? def __setattr__(self, key, value): ? ? ? ? pass not_fun = NotFun() print(not_fun.name)
由于__setattr__中并沒(méi)有將屬性注冊(cè)到__dict__中,所以not_fun對(duì)象并沒(méi)有name屬性,因此最后的print(not_fun.name)會(huì)報(bào)出屬性不存在的錯(cuò)誤:
AttributeError Traceback (most recent call last)
<ipython-input-21-6158d7aaef71> in <module>()
8 pass
9 not_fun = NotFun()
---> 10 print(not_fun.name)AttributeError: 'NotFun' object has no attribute 'name'
所以,重載__setattr__時(shí)必須要考慮是否在__dict__中進(jìn)行屬性注冊(cè)。
總結(jié):
python的實(shí)例屬性的定義、獲取和管理可以通過(guò)__setattr__()和__dict__配合進(jìn)行,當(dāng)然還有對(duì)應(yīng)的__getattr__()方法,本文暫時(shí)不做分析。__setattr__()方法在類的屬性賦值時(shí)被調(diào)用,并通常需要把屬性名和屬性值存儲(chǔ)到self的__dict__字典中。
到此這篇關(guān)于python魔法方法之__setattr__()的文章就介紹到這了,更多相關(guān)python魔法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用python將xml文件解析成html文件的實(shí)現(xiàn)方法
下面小編就為大家分享一篇利用python將xml文件解析成html文件的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12python學(xué)習(xí)之panda數(shù)據(jù)分析核心支持庫(kù)
這篇文章主要給大家介紹了關(guān)于python學(xué)習(xí)之panda數(shù)據(jù)分析核心支持庫(kù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05使用python實(shí)現(xiàn)excel的Vlookup功能
這篇文章主要介紹了使用python實(shí)現(xiàn)excel的Vlookup功能,當(dāng)我們想要查找的數(shù)據(jù)量較大時(shí),這時(shí)則有請(qǐng)我們的主角VLookup函數(shù)出場(chǎng),那么如何用python實(shí)現(xiàn)VLookup呢,需要的朋友可以參考下2023-04-04Pytorch搭建yolo3目標(biāo)檢測(cè)平臺(tái)實(shí)現(xiàn)源碼
這篇文章主要為大家介紹了Pytorch搭建yolo3目標(biāo)檢測(cè)平臺(tái)實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python動(dòng)態(tài)賦值的陷阱知識(shí)點(diǎn)總結(jié)
在本文中我們給大家整理了關(guān)于Python動(dòng)態(tài)賦值的陷阱的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的朋友們學(xué)習(xí)下。2019-03-03Python?實(shí)現(xiàn)驅(qū)動(dòng)AI機(jī)器人
這篇文章主要介紹了Python?實(shí)現(xiàn)驅(qū)動(dòng)AI機(jī)器人,下文圍繞利用Python?實(shí)現(xiàn)驅(qū)動(dòng)AI機(jī)器人的相關(guān)資料展開(kāi)內(nèi)容,需要的小伙伴可以參考一下2022-02-02Python生成隨機(jī)數(shù)組的方法小結(jié)
這篇文章主要介紹了Python生成隨機(jī)數(shù)組的方法,結(jié)合實(shí)例形式總結(jié)分析了Python使用random模塊生成隨機(jī)數(shù)與數(shù)組操作相關(guān)技巧,需要的朋友可以參考下2017-04-04python詞云庫(kù)wordcloud自定義詞云制作步驟分享
這篇文章主要介紹了python詞云庫(kù)wordcloud自定義詞云制作步驟分享,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08