• python __setattr__、__getattr__、__getattribute__全面详解


    一、属性引用函数

    hasattr(obj,name[,default])
    getattr(obj,name)
    setattr(obj,name,value)
    delattr(obj,name)

    二、属性引用重载


    def __setattr__(self,key,value): 
      1.拦截所有属性的赋值语句。
      2.self.attr=value 相当于 self.__setattr__("attr",value)。
      3.如果在__setattr__中对任何self属性赋值,都会再调用__setattr__,导致无穷递归循环。只能self.__dict__["attr"]=value 。

    def __getattribute__(self, key): 
      1.拦截所有的属性获取,包括未定义的属性,self.__dict__,等点号运算。
      2.所有的属性先在__getattribute__中没有找到,就会抛出AttributeError,__getattr__接收这个错误,此时进入__getattr__中继续寻找。
      3.如果__getattribute__没有抛出AttributeError,将不会调用__getattr__。


    def __getattr__(self, key): 
      拦截self.attr运算。当在__dict__中未找到该属性时,在类属性中也没有找到该属性,并且在继承树中也没有找到该属性,就会调用这个方法。


    def __delattr__(self,key): 删除属性

    三、示例

    class Square:  # 正方形
    
        def __init__(self, l):
            self.length = l  # 边长
    
        def __getattr__(self, key):
            if key == "area":
                return "__getattr__被调用了,为了area"
    
    
    sq = Square(10)
    print(sq.length)  # 10
    print(sq.area)  # __getattr__被调用了,为了area
    class Square:  # 正方形
    
        def __init__(self, l):
            pass
    
        def __getattr__(self, key):
            print("__getattr__被调用了")
            if key == "length":
                return 1111
    
        def __getattribute__(self, key123):
            print("__getattribute__被调用了")
            # return 123456
            raise AttributeError
    
    
    sq = Square(10)
    print(sq.length)
    # __getattribute__被调用了
    # __getattr__被调用了
    # 1111
    class Square:  # 正方形
    
        def __init__(self,l):
            pass
    
        def __getattr__(self, key):
            print("__getattr__被调用了")
            raise AttributeError("1111111")
    
        def __getattribute__(self, key123):
            print("__getattribute__被调用了")
            return 123456
            # raise AttributeError
    
    
    sq = Square(10)
    print(sq.length)
    # __getattribute__被调用了
    # 123456
    class Square:  # 正方形
    
        def __init__(self, l):
            self.length = l  # 边长
    
        def __setattr__(self, key, value):
            print("调用__setattr__", "key=", key)
            if key == "perimeter":
                self.__dict__["length"] = value / 4
                self.__dict__["perimeter"] = value
            if key == "length":
                self.__dict__["length"] = value
                self.__dict__["perimeter"] = value * 4
    
        def __getattr__(self, key):
            print("调用__getattr__ ,", "key =", key)
            if key == "area":
                return 960
    
        def __getattribute__(self, key123):
            print("调用__getattribute__ ,", "key123 =", key123)
            return object.__getattribute__(self, key123)
    
    
    sq = Square(10)
    # 调用__setattr__
    # 调用__getattribute__ , key123 = __dict__      此时执行self.__dict__["length"] = value
    # 调用__getattribute__ , key123 = __dict__      此时执行self.__dict__["perimeter"] = value * 4
    
    
    print(sq.length)
    # 调用__getattribute__ , key123 = length      此时执行self.length = l  # 边长
    
    print(sq.perimeter)
    # 调用__getattribute__ , key123 = perimeter
    # 40
    
    print(sq.area)
    # 调用__getattribute__ , key123 = area
    # 调用__getattr__ , key = area
    # 960
  • 相关阅读:
    2.6.2 AMQP协议和RabbitMQ基础
    2.6.1 消息队列介绍
    解决VS2015启动时Package manager console崩溃的问题
    项目管理实践
    Android动画之淡入淡出
    Android学习笔记
    Android: 解决ADB server didn't ACK
    Android: 实例解析Activity生命周期
    解决Window Azure: Failed to start Development Storage: the SQL Server instance ‘localhostSQLExpress’ could not be found.
    Spring注解之 Transactional
  • 原文地址:https://www.cnblogs.com/wwxbi/p/7751778.html
Copyright © 2020-2023  润新知