Я хотел бы выполнить некоторую проверку типов значений, которые передаются в список.
До сих пор я сделал несколько дескрипторов, таких как 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))
Итак, в конструкторе я передаю имя и тип значения, что должно гарантировать, что каждый элемент в списке должен быть определенного типа.
Как я должен быть в состоянии сделать это?
isinstance(element, self.value_type)
? Если да, то вы можете добавить:if not all([isinstance(element, self.value_type) for element in value]): raise TypeError("{} elements type must be {}".format(self.name, self.value_type))
- person Frodon   schedule 18.01.2017a = ListField('a', list)
, затемa.append([1])
работает, ноa.append(1)
вызывает ошибку - person hansaplast   schedule 18.01.2017