当前位置 博文首页 > 文章内容

    getattribute,__getattribute__与__getattr比较

    作者:dlxiaoyu01 栏目:其他 时间:2021-03-28 17:26:02

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



        参加校招的时候被面试官问到了,没能答上,主要是混淆了__getattribute__和__getattr__两个魔法方法。因此这里笔记一下。
        首先我们看看如何访问一个对象的属性:
        class A(object):
        def __init__(self):
        self.name = "Bob"
        self.age = 18
        self.gender  = "male"
        if __name__ == "__main__":
        a = A()
        print(a.name)
        print(a.age)
        print(a.gender)
        # 输出:
        #Bob
        #18
        #male
        如果我们想改变访问属性的逻辑,如执行a.age语句并非返回18,而是返回问年龄是不礼貌的行为。这里就可以用__getattribute__方法拦截属性,实现我们想要实现的逻辑。
        class A(object):
        def __init__(self):
        self.name = "Bob"
        self.age = 18
        self.gender  = "male"
        def __getattribute__(self, attr):
        # 拦截age属性
        if attr == "age":
        return "问年龄是不礼貌的行为"
        # 非age属性执行默认操作
        else:
        return object.__getattribute__(self, attr)
        if __name__ == "__main__":
        a = A()
        print(a.age)
        print(a.name)
        print(a.gender)
        # 输出:
        #问年龄是不礼貌的行为
        #Bob
        #male
        事实上,在实例化的对象进行.操作的时候(形如:a.xxx/a.xxx()),都会自动去调用__getattribute__方法。但是,如果某个属性在__getattribute__方法中未能找到,此时会调用__getattr__方法。
        如我们访问对象a中不存在的属性,会得到异常。比方执行print(a.NAME)语句,运行结果如下:
        AttributeError: 'A' object has no attribute 'NAME'
        但我就想无论是a.NAME,a.Name,还是a.NaME等等,即n a m e(包含大小写)四个元素组成的属性,访问结果都同a.name一样,可以做如下处理:
        class A(object):
        def __init__(self):
        self.name = "Bob"
        self.age = 18
        self.gender  = "male"
        def __getattr__(self, attr):
        return eval("self."+attr.lower()) #即:再次去执行__getattribute__方法
        if __name__ == "__main__":
        a = A()
        print("a.name -> {}".format(a.name))
        print("a.NAME -> {}".format(a.NAME))
        print("a.Name -> {}".format(a.Name))
        print("a.NaME -> {}".format(a.NaME))
        # 输出:
        #a.name -> Bob
        #a.NAME -> Bob
        #a.Name -> Bob
        #a.NaME -> Bob
        总结:
        1.__getattribute__方法优先级比__getattr__高
        2.只有在__getattribute__方法中找不到对应的属性时,才会调用__getattr__
        3.如果是对不存在的属性做处理,尽量把逻辑写在__getattr__方法中
        4.如果非得重写__getattribute__方法,需要注意两点:第一是避免.操作带来的死循环;第二是不要遗忘父类的__getattribute__方法在子类中起的作用
        ————————————————
     
        原文链接:https://blog.csdn.net/qq_41359051/article/details/82930939