Python基础详解之描述符
基本概念
描述符是将某种特殊类型的类的实例分配给另一个类的属性。这个特殊类型的类需要实现__get__、set、__delete__这三个方法中的至少一个。当属性被访问时(读、写或删除),相应的描述符方法就会被调用。
描述符的分类
Python中描述符可以分为数据描述符和非数据描述符两种类型:
- 数据描述符:同时实现了__get__和__set__方法的描述符
- 非数据描述符:只实现了__get__方法的描述符
描述符的应用场景
描述符可用于对各种属性进行控制,例如:
- 类型检查:通过实现__set__方法,在赋值操作时检查值的类型是否正确
- 值的范围限制:通过实现__set__方法,在赋值操作时检查值是否在指定范围之内
- 计数器:通过在__get__和__set__方法中实现计数器,并在每次访问属性时自动增加计数器的值
- 缓存:通过在__get__方法中实现缓存机制,将属性值缓存起来,避免不必要的计算等操作
示例一:类型检查
class TypedProperty:
def __init__(self, name, data_type):
self.name = name
self.data_type = data_type
def __set__(self, instance, value):
if not isinstance(value, self.data_type):
raise TypeError(f"Expected {self.data_type}, but got {type(value)}.")
instance.__dict__[self.name] = value
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
class Person:
name = TypedProperty('name', str)
age = TypedProperty('age', int)
p1 = Person()
p1.name = 'Tom'
p1.age = '18' # 这里会出现TypeError
在上面的例子中,我们定义了一个TypedProperty的描述符类,用于对属性的类型进行检查。在类Person中,我们定义了两个属性name和age,并将其赋值给TypedProperty描述符类的实例。当我们给p1的name和age属性赋值时,会先调用TypedProperty描述符类的__set__方法进行类型检查,如果检查不通过,则会抛出TypeError异常。
示例二:计数器
class Counter:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
if instance is None:
return self
instance.__dict__['_count'] += 1
return instance.__dict__[self.name]
def __set__(self, instance, value):
instance.__dict__[self.name] = value
class Person:
name = Counter('name')
p1 = Person()
p1.name = 'Tom'
p1.name = 'Mary'
print(p1._count) # 输出2
在上面的例子中,我们定义了一个Counter的描述符类,用于实现计数器功能。在类Person中,我们定义了属性name,并将其赋值给Counter描述符类的实例。当我们给p1的name属性赋值时,会自动调用Counter描述符类的__get__和__set__方法,每次访问时自动增加计数器_count的值,最终输出_count的值为2。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python基础详解之描述符 - Python技术站