Python 属性__getattribute__
首先理解__getattribute__的用法,先看代碼:
class Tree(object):def __init__(self,name):self.name = nameself.cate = "plant"def __getattribute__(self,obj):print("哈哈")return object.__getattribute__(self,obj)
aa = Tree("大樹")
print(aa.name)
執行結果是:
哈哈
大樹
為什么會這個結果呢?
__getattribute__是屬性訪問攔截器,就是當這個類的屬性被訪問時,會自動調用類的__getattribute__方法。即在上面代碼中,當我調用實例對象aa的name屬性時,不會直接打印,而是把name的值作為實參傳進__getattribute__方法中(參數obj是我隨便定義的,可任意起名),經過一系列操作后,再把name的值返回。Python中只要定義了繼承object的類,就默認存在屬性攔截器,只不過是攔截后沒有進行任何操作,而是直接返回。所以我們可以自己改寫__getattribute__方法來實現相關功能,比如查看權限、打印log日志等。如下代碼,簡單理解即可:
class Tree(object):def __init__(self,name):self.name = nameself.cate = "plant"def __getattribute__(self,*args,**kwargs):if args[0] == "大樹"print("log 大樹")return "我愛大樹"else:return object.__getattribute__(self,*args,**kwargs)
aa = Tree("大樹")
print(aa.name)
print(aa.cate)
結果是:
log 大樹
我愛大樹
plant
另外,注意注意:
初學者用__getattribute__方法時,容易栽進這個坑,什么坑呢,直接看代碼:
class Tree(object):def __init__(self,name):self.name = nameself.cate = "plant"def __getattribute__(self,obj):if obj.endswith("e"):return object.__getattribute__(self,obj)else:return self.call_wind()def call_wind(self):return "樹大招風"
aa = Tree("大樹")
print(aa.name)#因為name是以e結尾,所以返回的還是name,所以打印出"大樹"
print(aa.wind)#這個代碼中因為wind不是以e結尾,#所以返回self.call_wind的結果,打印的是"樹大招風"
上面的解釋正確嗎?
先說結果,關于print(aa.name)的解釋是正確的,但關于print(aa.wind)的解釋不對,為什么呢?我們來分析一下,執行aa.wind時,先調用__getattribute__方法,經過判斷后,它返回的是self.call_wind(),即self.call_wind的執行結果,但當去調用aa這個對象的call_wind屬性時,前提是又要去調用__getattribute__方法,反反復復,沒完沒了,形成了遞歸調用且沒有退出機制,最終程序就掛了!
總結
以上是生活随笔為你收集整理的Python 属性__getattribute__的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pandas以前笔记
- 下一篇: scipy csr_matrix csc