• python笔记61


    前言

    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

  • 相关阅读:
    Windows 显示隐藏文件
    Python 程序一行代码解决乘法口诀表
    【转发】基于Bert-NER构建特定领域的中文信息抽取框架(上)
    【转发】GET和POST两种基本请求方法的区别
    【转发】实现yolo3模型训练自己的数据集总结
    第十章集合总结
    2016-2017 201671010134 异常处理
    JAVA基础编程
    2016-2017 201671010134 第六章总结
    java总结
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15160890.html
Copyright © 2020-2023  润新知