Python装饰器14-描述器

描述器

这是Python一个重要的概念,英文名:Descriptor

descriptor是对象的一个属性,只不过它存在于类的dict中并且有特殊方法get(可能还有set和__delete)而具有一点特别的功能,为了方便指代这样的属性,我们给它起了个名字叫descriptor属性

虽然如此,还是看起来很难理解

标准的描述器对象定义如下:

class Des:

    def __init__(self):
        self.value = ''
    
    def __get__(self, instance, owner):
        print('returned from des obj')
        return self.value
    
    def __set__(self, instance, value):
        print('set in des obj')
        self.value = value

    def __delete__(self, instance):
        print('delete in des obj')
        del self.value

class Foo:
    d = Des()

f = Foo()
f.d = 10
print(f.d)

普通对象、描述器作为类属性、描述器对象作为类实例属性

class Des:

    def __init__(self):
        self.value = ''
    
    def __get__(self, instance, owner):
        print('returned from des obj')
        return self.value
    
    def __set__(self, instance, value):
        print('set in des obj')
        self.value = value

    def __delete__(self, instance):
        print('delete in des obj')
        del self.value

class Nor:
    def __init__(self):
        self.value = 10
    

class Foo:
    d = Des()
    n = Nor()

    def __init__(self):
        self.dd = Des()

f = Foo()
f.d = 10
print(f.d)

# 说明描述器对象必须是类的属性,不能是实例的属性
f.dd.value = 20
print(f.dd.value)

# 普通对象的访问
f.n.value = 30
print(f.n.value)

# 无法通过.直接访问描述器对象的属性
print(f.d.value)

运行结果:

set in des obj
returned from des obj
10
20
30
returned from des obj
Traceback (most recent call last):
  File "descriptor2.py", line 39, in 
    print(f.d.value)
AttributeError: 'int' object has no attribute 'value'

小结

关于描述器的讲解不止于上述内容,可以继续参考Python的官方文档,我们只需要记住以上部分内容,便于后续理解类作为装饰器。

  1. 描述器对象是类的属性才可以使用get
  2. 描述器对实例的赋值和取值都是通过getset进行,此时类退化为Data Descriptor,也可以理解为这个类只是对一个数据进行描述。

你可能感兴趣的:(Python装饰器14-描述器)