這篇文章主要介紹了Python魔法方法之__getattr__和getattribute是什么,具有一定借鑒價(jià)值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
讓客戶(hù)滿(mǎn)意是我們工作的目標(biāo),不斷超越客戶(hù)的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶(hù),將通過(guò)不懈努力成為客戶(hù)在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、網(wǎng)站空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、伊金霍洛網(wǎng)站維護(hù)、網(wǎng)站推廣。
在Python中有這兩個(gè)魔法方法容易讓人混淆:__getattr__和getattribute。通常我們會(huì)定義__getattr__而從來(lái)不會(huì)定義getattribute,下面我們來(lái)看看這兩個(gè)的區(qū)別。
__getattr__魔法方法
class MyClass: def __init__(self, x): self.x = x def __getattr__(self, item): print('{}屬性為找到!'.format(item)) return None >>> obj = MyClass(1) >>> obj.x 1 >>> obj.y y屬性為找到! None
我們定義一個(gè)MyClass類(lèi),設(shè)置一個(gè)實(shí)例屬性為x,值為1。obj為這個(gè)類(lèi)的實(shí)例,獲取obj.x返回1,而獲取obj.y發(fā)現(xiàn)屬性找不到,原因是obj的實(shí)例變量中不包含y,找不到某屬性時(shí)會(huì)調(diào)用__getattr__方法。
**調(diào)用__getattr__詳細(xì)過(guò)程如下:**
obj.attr
1.首先會(huì)在對(duì)象的實(shí)例屬性中尋找,找不到執(zhí)行第二步
2.來(lái)到對(duì)象所在的類(lèi)中查找類(lèi)屬性,如果還找不到執(zhí)行第三步
3.來(lái)到對(duì)象的繼承鏈上尋找,如果還找不到執(zhí)行第四步
4.調(diào)用obj.__getattr__方法,如果用戶(hù)沒(méi)有定義或者還是找不到,拋出AttributeError異常,屬性查找失?。?/p>
class MyClass: def __init__(self, x): self.x = x >>> obj = MyClass(1) >>> obj.y AttributeError: 'MyClass' object has no attribute 'a'
如上代碼,沒(méi)有定義__getattr__魔法方法,又找不到屬性,就會(huì)拋出異常。
__getattribute__魔法方法
當(dāng)我們調(diào)用對(duì)象的屬性時(shí),首先會(huì)調(diào)用__getattribute__魔法方法。
obj.x obj.__getattribute__(x)
如上代碼,這兩個(gè)代碼其實(shí)是等價(jià)的。當(dāng)__getattribute__查找失敗,就會(huì)去調(diào)用__getattr__方法。
代碼演示
class MyClass: def __init__(self, x): self.x = x def __getattribute__(self, item): print('正在獲取屬性{}'.format(item)) return super(MyClass, self).__getattribute__(item) >>> obj = MyClass(2) >>> obj.x 正在獲取屬性x 2
我們使用__getattribute__魔法方法時(shí),要返回父類(lèi)的方法,不然很難寫(xiě)對(duì),下面代碼是一個(gè)陷阱,會(huì)產(chǎn)生無(wú)限遞歸。
class MyClass: def __init__(self, x): self.x = x def __getattribute__(self, item): print('正在獲取屬性{}'.format(item)) return self.item >>> obj = MyClass(2) >>> obj.x File "xxx", line 11, in __getattribute__ print('正在獲取屬性{}'.format(item)) RecursionError: maximum recursion depth exceeded while calling a Python object
上面的代碼看起來(lái)似乎是對(duì)的,但卻調(diào)入了無(wú)限遞歸的陷阱,相當(dāng)于
def __getattribute__(self, item): print('正在獲取屬性{}'.format(item)) return self.__getattribute__(item)
要十分警惕。
另外,內(nèi)置的getattr和hasattr也會(huì)觸發(fā)這個(gè)魔法方法。
>>> getattr(obj, 'x', None) 正在獲取屬性x 2 >>> hasattr(obj, 'x', None) 正在獲取屬性x True
其他細(xì)節(jié)需要注意
class MyClass: x = 999 def __init__(self, x): self.x = x def __getattribute__(self, item): print('正在獲取屬性{}'.format(item)) return super(MyClass, self).__getattribute__(item)
上面代碼中,定義了一個(gè)類(lèi)屬性x和一個(gè)實(shí)例屬性x,這兩個(gè)屬性同名,根據(jù)Python語(yǔ)法規(guī)則,當(dāng)對(duì)象獲取屬性x的時(shí)候,首先會(huì)在實(shí)例屬性中尋找,如果找不到才回去類(lèi)屬性中查找。
>>> obj = MyClass(2) >>> print(obj.x) 正在獲取屬性x 2 >>> del obj.x #刪除了實(shí)例屬性x >>> print(obj.x) #此時(shí)訪(fǎng)問(wèn)的是類(lèi)屬性 正在獲取屬性 999
這樣就能印證了上面所說(shuō)__getattribute__的查找順序。通常該方法在框架中可能會(huì)用到,一般情況下無(wú)需使用。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享Python魔法方法之__getattr__和getattribute是什么內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問(wèn)題就找創(chuàng)新互聯(lián),詳細(xì)的解決方法等著你來(lái)學(xué)習(xí)!
當(dāng)前題目:Python魔法方法之__getattr__和getattribute是什么
網(wǎng)站地址:http://www.muchs.cn/article36/pcoosg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶(hù)體驗(yàn)、Google、手機(jī)網(wǎng)站建設(shè)、服務(wù)器托管、微信公眾號(hào)、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)