zoukankan      html  css  js  c++  java
  • 浅谈__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.NAMEa.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__方法在子类中起的作用

    作者:Nobita Chen

    -----------------------------------------------

    慢慢的,你总会发现,你的努力没有白费。

  • 相关阅读:
    个人作业1——四则运算题目生成程序
    软件工程的实践项目课程的自我目标
    个人附加作业
    个人作业3——个人总结(Alpha阶段)
    结对编程2——单元测试
    个人作业二——英语学习APP 案例分析
    结对编程 (201421123002,201421123006,201421123007)
    四则运算
    软件工程的实践项目课程的自我目标
    个人作业3——个人总结(Alpha阶段)
  • 原文地址:https://www.cnblogs.com/chenshengkai/p/13737835.html
Copyright © 2011-2022 走看看