我想对传递给列表的值进行一些类型检查。
到目前为止,我已经制作了一些像CharField和IntegerField这样的描述符,它们可以很好地工作。
列表描述符我无法工作。
基本字段类:
class Field(object):
def __init__(self, type_, name, default=None, required=False):
self.type = type_
self.name = "_" + name
self.required = required
self._default = default
def __get__(self, instance, owner):
return getattr(instance, self.name, self.default)
def __set__(self, instance, value):
raise NotImplementedError
def __delete__(self, instance):
raise AttributeError("Can't delete attribute")
@property
def default(self):
return self._default
@default.setter
def default(self, value):
self._default = value if value else self.type()
我的CharField课程:
class CharField(Field):
def __init__(self, name, default=None, min_length=0, max_length=0, strip=False):
super(CharField, self).__init__(unicode, name, default=default)
self.min_length = min_length
self.max_length = max_length
self.strip = strip
def __set__(self, instance, value):
if not isinstance(value, (unicode, str)):
raise TypeError("{} must be a string or unicode".format(self.name))
if self.strip:
value = value.strip()
if self.min_length and len(value) < self.min_length:
raise ValueError("{} must have a minimum length of {}".format(self.name, self.min_length))
if self.max_length and len(value) > self.max_length:
raise ValueError("{} must have a maximum length of {}".format(self.name, self.max_length))
setattr(instance, self.name, value)
然后是ListField类:
class ListField(Field):
def __init__(self, name, value_type):
super(ListField, self).__init__(list, name, default=[])
self.value_type = value_type
def __set__(self, instance, value):
if not isinstance(value, list):
raise TypeError("{} must be a list".format(self.name))
setattr(instance, self.name, value)
def append(self, value):
if not isinstance(value, self.value_type):
raise ValueError("Value is list {} must be of type {}".format(self.name, self.value_type))
所以在构造函数中我传递一个名称和一个value_type,这应该确保列表中的每个项目都应该是某种类型。
我该怎么做?
答案 0 :(得分:0)
感谢您的回答以及我开展的更多研究。
class ListField(Field):
def __init__(self, name, value_type):
super(ListField, self).__init__(list, name, default=[])
self.value_type = value_type
def __set__(self, instance, value):
if not isinstance(value, list):
raise TypeError("{} must be a list".format(self.name))
setattr(instance, self.name, value)
def __iter__(self):
for item in self.default:
yield item
def __len__(self):
return len(self.default)
def __getitem__(self, item):
return self.default[item]
def append(self, value):
if not isinstance(value, self.value_type):
raise TypeError("Value is list {} must be of type {}".format(self.name, self.value_type))
self.default.append(value)
与其他字段不同,可以覆盖此字段而不会抛出错误,但是现在这样做。