【Python】描述器

描述器

概念

描述器:python中,一个类实现了__get__,__set__.__delete__的三个方法中的任意一个就是描述器
分类:数据描述器(含有__get__和__set__方法),非数据描述器(仅有__get__)
补充:
如果一个类的类属性,设置为描述器,那么这个类被称为owner属主,method也是类的属性
用到三个魔术方法,__get__(), __set__(), __delete__()
方法签名如下
object.__get__(self,instance,owner)
object.__set__(self,instance,value)
object.__delete(self,instance)
self:当前实例,调用者(描述器类的实例)
instance:owner的实例(即描述器的所属类的实例)
owner:属性的所属的类(即描述器的所属类)
描述器生效的基类:只有当描述器类和描述器拥有类都为新式类class xx(object)时才生效。
描述器属性调用优先级:数据描述器属性 > 实例属性 > 非数据描述器

描述器属性优先级

# 描述器类
class Age(object):
    # 获取属性操作绑定
    def __get__(self, instance, owner):
        print("get")

    # 设置属性操作绑定
    def __set__(self, instance, value):
        print("set")

    # 删除属性操作绑定
    def __delete__(self, instance):
        print("del")
      
# 描述器拥有类
class Person(object):
    # 实例化age属性的描述器
    age = Age()

    # 初始化实例
    def __init__(self):
        print("实例属性")
        self.age = 20

p1 = Person()
p1.age = 10
print(p1.age)
del p1.age
>>实例属性
>>set
>>set
>>get
>>None
>>del
  • 结论:数据描述器属性调用优先级大于实例属性
# 描述器类
class Age(object):
    # 获取属性操作绑定
    def __get__(self, instance, owner):
        # 实例属性优先级大于非数据描述器,所以该部分不会被执行
        print("get")

# 描述器拥有类
class Person(object):
    # 实例化age属性的描述器
    age = Age()
    # 初始化实例
    def __init__(self):
        print("实例属性")
        self.age = 20

p1 = Person()
p1.age = 10
print(p1.age)
>>实例属性
>>10
  • 结论:实例属性调用优先级大于非数据描述器

设计一个属性描述器

# 描述器类
class Age(object):
    # 获取属性操作绑定
    def __get__(self, instance, owner):
        return instance.v

    # 设置属性操作绑定
    def __set__(self, instance, value):
        if value > 0:
            # 将值绑定在owner的实例instance上(即Person的实例化对象p上)
            instance.v = value

    # 删除属性操作绑定
    def __delete__(self, instance):
        print("delete")
        del instance.v

# 描述器拥有类
class Person(object):
    # 实例化age属性的描述器
    age = Age()
    pass

p1 = Person()
p2 = Person()
p1.age = 10
p2.age = 20
print(p1.age)
print(p2.age)
del p1.age
del p2.age
>>10
>>20
>>delete
>>delete
  • age属性输出结果值并没有受两次赋值操作互相影响,此时通过将值绑定在已经实现不同的Person实例操作不同的age的描述器
发布了82 篇原创文章 · 获赞 468 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_44647926/article/details/104673380