python笔记-面向对象-定制属性访问-描述符

一、定制属性访问

1.1 修改、新增属性: object.name=valuesetattr(object:Any, name:str, value:Any)

属性存在就修改, 否则增加. 会触发 __setattr__ 方法

class Cat:
    name = "花花"
    sex = "female"
    age = "2years"

    def __setattr__(self, key, value):  # 当属性被修改或增加属性时触发此方法
        print("修改属性")
        self.__dict__[key] = value


cat = Cat()

setattr(cat, "name", "小花")

print(cat.name)

cat.age = "3years"
print(cat.age)

1.2 查询: object.attrgetattr(object:Any, name: str)

查询属性, 如果存在就返回属性值, 不存在则报错. 会触发 __getattribute__方法

class Cat:
    name = "花花"
    sex = "female"
    age = "2years"

    def __getattribute__(self, item):  # 查询属性时触发方法
        print(f"查询属性: {item}")
        return object.__getattribute__(self, item)


cat = Cat()

print(cat.age)
print(getattr(cat, "age"))

1.3 删除del object.namedelattr(object:Any, name:str)

从对象内存空间中删除属性name, 触发 __delattr__ 方法

class Cat:
    name = "花花"
    sex = "female"
    age = "2years"

    def __delattr__(self, item):  # 删除属性时触发次方法. 
        print(f"删除属性: {item}")
    


cat = Cat()
delattr(cat, "name")

1.4 查询属性是否存在hasattr(object:Any, name: Any)

会去查询对象的属性,如果不存在发生触发异常,则返回False,否则返回True

查询方式: 调用 __getattribute__ 方法, 如果报错, 这属性不存在, 返回False. 如果不报错, 属性存在, 返回True

class Cat:
    name = "花花"
    sex = "female"
    age = "2years"

    def __getattribute__(self, item):
        print(f"查询属性: {item}")
        return object.__getattribute__(self, item)


cat = Cat()
print(hasattr(cat, "nae"))  # hasttr更具 __getattribute__ 是否出现异常来判断属性是否存在

补充
__getattr__方法: 查询属性不存在时, 触发此方法

class Cat:
    name = "花花"
    sex = "female"
    age = "2years"

    def __getattribute__(self, item):
        print(f"查询属性: {item}")
        return object.__getattribute__(self, item)

    def __getattr__(self, item):
        print(f"查询属性: {item}, 不存在")


cat = Cat()
print(hasattr(cat, "nae"))

二、描述符

当一个类的属性是另一个类的实例时,我们称这个属性为描述符。
如果通过当前类实例查看,修改,删除这个属性,会触发另一个类的__get____set____delete__方法


class Cls1:
    def __get__(self, instance, owner):
        print('获取')

    def __set__(self, instance, value):
        print('设置')

    def __delete__(self, instance):
        print('删除')


class Cls2:
    ins = Cls1()  # 描述符


# 当类的属性是另一个类的实例时,此属性成为描述符
cls2 = Cls2()
# cls2.ins  # 会触发类Cls1的 __get__ 方法
# cls2.ins = 1 # 会触发Cls1的 __set__ 方法
# del cls2.ins # 会触发Cls1的 __delete__ 方法
原文地址:https://www.cnblogs.com/duyupeng/p/13160970.html