object 類里面有個(gè) __getattribute__
方法,作用是類實(shí)例化調(diào)用屬性和方法的時(shí)候都會(huì)調(diào)用一次,返回該類的屬性。
如果調(diào)用的屬性沒有,會(huì)拋出 AttributeError 異常。如果屬性查找(attribute lookup)在實(shí)例以及對(duì)應(yīng)的類中(通過__dict__
)失敗, 那么會(huì)調(diào)用到類的__getattr__
方法。
A類在調(diào)用自身屬性的時(shí)候,是不會(huì)觸發(fā)__getattribute__()方法。
只有在調(diào)用A()實(shí)例屬性或方法的時(shí)候,才會(huì)觸發(fā)__getattribute__()方法
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
class A(object):
count = 0
def __init__(self):
self.name = "yoyo"
self.age = 18
def start(self):
print("start1111111")
def __getattribute__(self, item):
"""屬性攔截器"""
print("調(diào)用了A類的屬性:", item)
return object.__getattribute__(self, item)
a = A()
# A()實(shí)例對(duì)象屬性會(huì)調(diào)用__getattribute__
print(a.count)
print(a.age)
print(a.name)
print(a.start())
如果A類屬性(__dict__
)沒查找到,并且實(shí)例屬性和方法也沒找到,此時(shí)會(huì)拋出 AttributeError 異常
a = A()
print(a.weight) # 找不到屬性
運(yùn)行結(jié)果
調(diào)用了A類的屬性: weight
Traceback (most recent call last):
File "demo/aaa.py", line 27, in <module>
print(a.weight) # 找不到屬性
File "demo/aaa.py", line 18, in __getattribute__
return object.__getattribute__(self, item)
AttributeError: 'A' object has no attribute 'weight'
如果屬性查找(attribute lookup)在實(shí)例以及對(duì)應(yīng)的類中(通過__dict__
)失敗, 那么會(huì)調(diào)用到類的__getattr__
方法。
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
class A(object):
count = 0
def __init__(self):
self.name = "yoyo"
self.age = 18
def start(self):
print("start1111111")
def __getattribute__(self, item):
"""屬性攔截器"""
print("調(diào)用了A類的屬性:", item)
return object.__getattribute__(self, item)
def __getattr__(self, item):
"""屬性找不到會(huì)執(zhí)行這個(gè)方法"""
print("找不到該屬性:%s" % item)
return 'not found'
a = A()
# A()實(shí)例對(duì)象屬性會(huì)調(diào)用__getattribute__
print(a.count)
print(a.age)
print(a.weight)
運(yùn)行結(jié)果不會(huì)出現(xiàn)異常
調(diào)用了A類的屬性: count
0
調(diào)用了A類的屬性: age
18
調(diào)用了A類的屬性: weight
找不到該屬性:weight
not found
網(wǎng)上有個(gè)很經(jīng)典的使用示例,訪問字典的key,像訪問屬性一樣訪問字典。
字典取值有2種方式,通過dict[key] 和dict.get(key)的方式取值。
a = {
"name": "yoyo",
"age": 18
}
# 字典訪問
print(a["name"])
print(a.get("name"))
在其它語言里面,比如javascript里面可以把json當(dāng)一個(gè)object對(duì)象,通過a.name,a.age這種點(diǎn)的方式就能直接取值了。
于是我們自己寫一個(gè)類來實(shí)現(xiàn)這種方式
class ObjectDict(dict):
def __init__(self, *args, **kwargs):
super(ObjectDict, self).__init__(*args, **kwargs)
def __getattr__(self, name):
value = self[name]
if isinstance(value, dict):
value = ObjectDict(value)
return value
if __name__ == '__main__':
a = {
"name": "yoyo",
"age": 18
}
obj = ObjectDict(a)
print(obj.name)
print(obj.age)
也可以傳多個(gè)值
if __name__ == '__main__':
obj = ObjectDict(a={'age': 1, 'name': 'yoyo'}, d=True)
print(obj.a)
print(obj.a.name)
print(obj.d)
dict嵌套dict也可以通過.的方式取值
if __name__ == '__main__':
obj = ObjectDict(a={'age': 1,
'name': 'yoyo',
'data': {'id': 11, 'tel': 12345678900}}, d=True)
print(obj.a)
print(obj.a.name)
print(obj.a.data)
print(obj.a.data.id)
print(obj.a.data.tel)
運(yùn)行結(jié)果
{'age': 1, 'name': 'yoyo', 'data': {'id': 11, 'tel': 12345678900}}
yoyo
{'id': 11, 'tel': 12345678900}
11
12345678900
參考資料https://www.cnblogs.com/xybaby/p/6280313.html
聯(lián)系客服