描述符是实现了特定协议的类,这个协议包括 __get__、 __set__ 和 __delete__ 方法。描述符的用法是,创建一个实例,作为另一个类的类属性。
class Check:
def __init__(self, name):
self.name = name # Person实例中属性的名称
def __set__(self, instance, value): # 尝试为Person实例赋值时,会调用此方法,self是描述符实例,instance是实例,value 要设定的值
if value > 0:
instance.__dict__[self.name] = value
else:
raise ValueError('value must be > 0')
def __get__(self, instance, owner): # self是描述符实例,instance是实例, owner实例类的引用如Person
return instance.__dict__[self.name]
class Person:
height = Check('height')
def __init__(self, height):
self.height = height
>>> p = Person(180)
>>> p.height
180
>>> vars(p)
自动获取储存属性的名称
class Check:
__counter = 0 # 实例数量统计
def __init__(self):
cls = self.__class__
prefix = cls.__name__
index = cls.__counter
self.name = '_{}#{}'.format(prefix, index) # 实例的实际保存名称(唯一)
cls.__counter += 1 # 计数器递增
def __set__(self, instance, value):
if value > 0:
setattr(instance, self.name, value) # 使用内置的setattr函数把值存储在instance中
else:
raise ValueError('height must be > 0')
def __get__(self, instance, owner):
if instance is None:
return self
else:
return getattr(instance, self.name)
class Person:
height = Check()
def __init__(self, height):
self.height = height
>>> p = Person(180)
>>>
>>> vars(p)
{'_Check#0': 180}
>>> p.height
180