前言object 类里面有个 __getattribute__ 方法,作用是类实例化调用属性和方法的时候都会调用一次,返回该类的属性。 如果调用的属性没有,会抛出 AttributeError 异常。如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__ )失败, 那么会调用到类的__getattr__ 方法。 __getattribute__方法A类在调用自身属性的时候,是不会触发__getattribute__()方法。 只有在调用A()实例属性或方法的时候,才会触发__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("调用了A类的属性:", item) return object.__getattribute__(self, item)
a = A() # A()实例对象属性会调用__getattribute__ print(a.count) print(a.age) print(a.name) print(a.start()) 如果A类属性(__dict__ )没查找到,并且实例属性和方法也没找到,此时会抛出 AttributeError 异常 a = A() print(a.weight) # 找不到属性 运行结果 调用了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' __getattr__方法如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__ )失败, 那么会调用到类的__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("调用了A类的属性:", item) return object.__getattribute__(self, item)
def __getattr__(self, item): """属性找不到会执行这个方法""" print("找不到该属性:%s" % item) return 'not found'
a = A() # A()实例对象属性会调用__getattribute__ print(a.count) print(a.age) print(a.weight) 运行结果不会出现异常 调用了A类的属性: count 0 调用了A类的属性: age 18 调用了A类的属性: weight 找不到该属性:weight not found 使用场景网上有个很经典的使用示例,访问字典的key,像访问属性一样访问字典。 字典取值有2种方式,通过dict[key] 和dict.get(key)的方式取值。 a = { "name": "yoyo", "age": 18 }
# 字典访问 print(a["name"]) print(a.get("name")) 在其它语言里面,比如javascript里面可以把json当一个object对象,通过a.name,a.age这种点的方式就能直接取值了。 于是我们自己写一个类来实现这种方式 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) 也可以传多个值 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) 运行结果 {'age': 1, 'name': 'yoyo', 'data': {'id': 11, 'tel': 12345678900}} yoyo {'id': 11, 'tel': 12345678900} 11 12345678900 参考资料https://www.cnblogs.com/xybaby/p/6280313.html
|