我不知道是什么
笨拙的
关于这一点,目前大多数语言都没有内置的getter/setter验证,因此您最终会用任何语言编写类似于此的内容-如果您希望通过验证将所有属性转换为getter/setter对,则必须分别编写它们。
现在,python是
非常
灵活的性质,所以有几种方法可以用来减少这个过程的冗长性(但不是复杂性)。例如,您可以创建自己的validator decorator,将其夹在setter的顶部,例如:
def validator(cmp, exc):
def decorator(setter): # a decorator for the setter
def wrapper(self, value): # the wrapper around your setter
if cmp(value): # if cmp function returns True, raise the passed exception
raise exc
setter(self, value) # otherwise just call the setter to do its job
return wrapper
return decorator
现在您可以定义getter/setter对,其中验证包括:
class User:
def __init__(self, age):
self.age = age
@property
def age(self):
return self._age
@age.setter
@validator(lambda x: x < 0, ValueError("Age can't be negative"))
def age(self, value):
self._age = value
但是,如果您只打算在setter(和getter)中进行验证,而不进行其他处理,那么您可以定义自己的
验证
属性并节省大量的冗长信息,例如:
class ValidatingProperty(object):
def __init__(self, prop, cmp, exc):
self.prop = prop
self.cmp = cmp
self.exc = exc
def __get__(self, instance, owner=None):
if instance is None:
return self
return getattr(instance, self.prop, None)
def __set__(self, instance, value):
if self.cmp(value):
raise self.exc
setattr(instance, self.prop, value)
def __delete__(self, instance):
delattr(instance, self.prop)
现在,您可以简单地构建类getter/setter,如下所示:
class User:
age = ValidatingProperty("_age", lambda x: x < 0, ValueError("Age can't be negative"))
def __init__(self, age):
self.age = age
如果需要访问原始属性(假设已设置),则
包装纸
围绕着它,你仍然可以用
self._age
(或任何你作为第一个论点传递给你的“不动产”
ValidatingProperty
)甚至可以单独构建验证器,这样就不需要依赖lambda(例如,创建
IntegerValidator
类,它允许您通过验证范围,然后在需要时重用)。
另一种选择是将类的用户视为成年人,并解释文档中的有效值,如果他们超出了这个范围,那么就有龙了。如果类打算用来自最终用户的数据填充,那么应该在收集最终用户数据的一侧执行验证(以便最终用户能够记住有意义的错误),而不一定是在模型本身中。