Python中的描述器如何使用
更新时间:2023-11-11Python中的描述器介绍
描述器是Python中一种特殊的协议,用于实现属性访问和对象的自定义行为。描述器主要包括三种类型:property、descriptor和protocol。简单来说,描述器就是实现了特殊的__get__, __set__和__delete__方法的类,它允许我们改变属性的读写行为、验证数据、使用智能默认值等等。
property描述器
property是Python的一种内置描述器,它能够将一个方法转换为属性,方便我们直接调用。当我们需要在获取属性值和设置属性值时进行额外的逻辑处理时,可以使用property。下面是一个简单的示例:
class Person: def __init__(self, name, age): self.name = name self._age = age @property def age(self): return self._age @age.setter def age(self, value): if value < 0: raise ValueError("Age cannot be negative.") self._age = value p = Person("Tom", 20) print(p.age) p.age = 30 print(p.age) p.age = -10 # 抛出异常
descriptor描述器
descriptor是自定义的描述器,它会覆盖掉对象的属性访问,包括读取、设置和删除属性。它的行为类似于property,但是它更加灵活,可以定义更多的行为。下面给出一个简单的示例:
class StringLength: def __init__(self, name): self.name = name def __get__(self, instance, cls): return len(getattr(instance, self.name)) def __set__(self, instance, value): if not isinstance(value, str): raise ValueError("String required.") setattr(instance, self.name, value) class Person: name = StringLength("name") age = 0 def __init__(self, name, age): self.name = name self.age = age p = Person("Tom", 20) print(p.name) p.name = "Jerry" print(p.name) p.name = 123 # 抛出异常
protocol描述器
protocol是另一种描述器,它可以像方法一样调用,但是它需要实现特定的协议函数,包括__get__、__set__、__delete__、__set_name__等。这种描述器是Python 3.6中新增的特性,它提供了更加灵活的行为。下面是一个简单的示例:
class String: def __init__(self): self.value = "" def __get__(self, instance, owner): return self.value def __set__(self, instance, value): if not isinstance(value, str): raise ValueError("String required.") self.value = value def __set_name__(self, owner, name): self.name = name class Person: name = String() def __init__(self, name): self.name = name p = Person("Tom") print(p.name) p.name = "Jerry" print(p.name) p.name = 123 # 抛出异常
总结
在Python中,描述器是非常强大的语言特性,允许我们自定义属性的行为,并且可以实现各种有趣的功能。Python内置的property描述器实现了基本的对象属性读取和设置逻辑,而自定义的descriptor和protocol描述器则提供了更加灵活的行为,让我们可以在属性设置时执行自定义的逻辑代码。熟练掌握和运用描述器可以使我们的Pyhthon程序变得更加强大和灵活。