python __setattr__、__getattr__、__getattribute__全面詳解

1、屬性引用函數函數

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

 

2、屬性引用重載code


def __setattr__(self,key,value): 
  1.攔截全部屬性的賦值語句。
  2.self.attr=value 至關於 self.__setattr__("attr",value)。
  3.若是在__setattr__中對任何self屬性賦值,都會再調用__setattr__,致使無窮遞歸循環。只能self.__dict__["attr"]=value 。blog

 

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): 刪除屬性遞歸

 

3、示例get

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
相關文章
相關標籤/搜索