설명자 프로토콜이 제대로 작동하지만 해결할 문제가 하나 있습니다. 이 서브 클래스입니다파이썬에서 설명자 프로토콜로 작업 할 때 어떻게 속성 이름을 얻을 수 있습니까?
class Field(object):
def __init__(self, type_, name, value=None, required=False):
self.type = type_
self.name = "_" + name
self.required = required
self._value = value
def __get__(self, instance, owner):
return getattr(instance, self.name, self.value)
def __set__(self, instance, value):
if value:
self._check(value)
setattr(instance, self.name, value)
else:
setattr(instance, self.name, None)
def __delete__(self, instance):
raise AttributeError("Can't delete attribute")
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = value if value else self.type()
@property
def _types(self):
raise NotImplementedError
def _check(self, value):
if not isinstance(value, tuple(self._types)):
raise TypeError("This is bad")
:
class Country(BaseModel):
name = CharField("name")
country_code_2 = CharField("country_code_2", min_length=2, max_length=2)
country_code_3 = CharField("country_code_3", min_length=3, max_length=3)
def __init__(self, name, country_code_2, country_code_3):
self.name = name
self.country_code_2 = country_code_2
self.country_code_3 = country_code_3
지금까지 너무 좋아,이 작품 : 사용
class CharField(Field):
def __init__(self, name, value=None, min_length=0, max_length=0, strip=False):
super(CharField, self).__init__(unicode, name, value=value)
self.min_length = min_length
self.max_length = max_length
self.strip = strip
@property
def _types(self):
return [unicode, str]
def __set__(self, instance, value):
if self.strip:
value = value.strip()
super(CharField, self).__set__(instance, value)
그리고는 모델 클래스이다
나는 기술자가 예상대로.
내가 여기있는 유일한 문제는 필드가 선언 될 때마다 필드 이름을 지정해야한다는 것입니다. 예 : country_code_2
필드의 경우 "country_code_2"
입니다.
모델 클래스의 속성 이름을 가져 와서 필드 클래스에서 사용할 수 있습니까?
제안 사항을 구현 한 후 업데이트를 추가했습니다. 이것 좀 봐 줄래? –
'six.with_metaclass()'를 올바르게 사용하지 않으면 기본 클래스로 사용해야합니다. http://stackoverflow.com/questions/18513821/python-metaclass-understanding-the-with-metaclass를 참조하십시오. 대신에'six'를 사용하기 전에 파이썬 2 또는 3에서 작동하게 만들기 시작할 수도 있습니다 :-) –
'six.with_metaclass()'를'__metaclass__ = BaseModelMeta'로 바꿉니다. (나는 Python 2를 사용하고있다) 이것은 같은 오류를 준다. –