Python 的描述器,可以让我们在设置属性值时,加入一些自定义的检查规则。
什么是描述器?
描述器其实是一种特殊类型的对象,它可以控制我们如何访问类的属性。通过定义几个特殊的方法,比如 get()、set() 和 delete(),我们就能拦截对属性的读取、修改和删除操作,并在这些操作发生时执行我们自己的代码。
制作一个简单的验证器
首先,创建一个基础的验证器类,这个类会实现描述器的基本功能,并提供一个框架来验证属性值。
from abc import ABC, abstractmethod
class Validator(ABC):
def __set_name__(self, owner, name):
self.private_name = '_' + name
def __get__(self, obj, objtype=None):
return getattr(obj, self.private_name)
def __set__(self, obj, value):
self.validate(value)
setattr(obj, self.private_name, value)
@abstractmethod
def validate(self, value):
pass
在这个基础类中:
__set_name__
方法在描述器被添加到类中时自动调用,用于生成一个私有的属性名来存储实际的值。__get__
方法用于获取属性值。__set__
方法用于设置属性值,并在执行设置前进行验证。validate
是一个抽象方法,需要在子类中具体实现验证逻辑。
定制自己的验证器
有了这个基础类,我们就可以轻松地创建自己的验证器了。比如:
- OneOf 验证器:确保值是指定选项中的一个。
class OneOf(Validator):
def __init__(self, *options):
self.options = set(options)
def validate(self, value):
if value not in self.options:
raise ValueError(f'Expected {value!r} to be one of {self.options!r}')
这个验证器可以用来限制某个属性的值必须是预定义的几个选项之一。
- Number 验证器:验证数字类型和范围。
class Number(Validator):
def __init__(self, minvalue=None, maxvalue=None):
self.minvalue = minvalue
self.maxvalue = maxvalue
def validate(self, value):
# 验证代码...
这个验证器可以确保属性值是一个数字,且在一定范围内。
- String 验证器:验证字符串长度和其他自定义条件。
class String(Validator):
def __init__(self, minsize=None, maxsize=None, predicate=None):
self.minsize = minsize
self.maxsize = maxsize
self.predicate = predicate
def validate(self, value):
# 验证代码...
该验证器可以检查一个字符串的长度,或者应用其他自定义的验证函数。
示例
假设我们有一个“Person”类,其中有一些属性需要验证:
class Person:
age = Number(minvalue=0, maxvalue=120)
name = String(minsize=2, maxsize=50)
status = OneOf("active", "inactive", "pending")
def __init__(self, name, age, status):
self.name = name
self.age = age
self.status = status
当尝试给这些属性设置不合法的值时,就会抛出一个错误。通过使用描述器,可以非常方便地为类的属性添加各种复杂的验证规则。