2017-01-18 1 views
2

목록으로 전달되는 값에 대한 유형 검사를하고 싶습니다.목록이있는 파이썬 2 설명자

지금까지 완벽하게 작동하는 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. 목록의 모든 항목이 특정 유형이어야합니다.

어떻게해야합니까?

+2

현재 구현에 어떤 문제가 있습니까? – hansaplast

+0

값 목록의 요소 유형을 'isinstance (element, self.value_type)'명령으로 비교할 수 있습니까? 만약 그렇다면 당신은 다음을 추가 할 수 있습니다 :'모두가 아니라면 (값의 요소에 대해 [isinstance (element, self.value_type)]) : raise TypeError ("{요소 유형이 {}이어야합니다. @hansaplast @hansaplast리스트에 값을 추가 할 때 타입 체크가 작동하지 않는다. – Frodon

+0

@ 1])'작동하지만'a.append (1)'오류가 발생합니다 –

답변

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) 

다른 필드와 달리이 필드는 오류를 발생시키지 않고 덮어 쓸 수 있지만 지금은이를 수행합니다.

관련 문제