zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    洛谷P2415 集合求和
    八数码难题解法大全
    P1789 【Mc生存】插火把
    P1554 梦中的统计
    CentOS6.4 安装 Oracle11g
    湖南省第八届大学生程序设计大赛原题 D
    选择排序(直接选择、堆排序)
    改变Emacs下的注释代码方式以支持当前行(未选中情况下)的注释/反注释
    cocos2d-x游戏开发(十五)游戏加载动画loading界面
    SIMPASS技术解析
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15160890.html
Copyright © 2011-2022 走看看