Насколько уродлив мой код, реализующий полиморфные модели? - PullRequest
2 голосов
/ 21 апреля 2010

Я использую Полиморфные модели .

Простой вопрос: Мой код ниже работает без использования этой строки ниже, что я вижу в коде других людей. Что он должен делать?

#super(GeneralModel, self).__init__(*args, **kwargs)

Грязный вопрос: У меня такое чувство, что мой код ниже, хотя, кажется, работает, не самое красивое решение.

Краткое изложение того, что я делаю: Я создаю (или создаю) новую сущность модели хранилища данных на основе «нечистого» объекта JSON, размещенного на сервере. Во-первых, я хочу выполнить некоторую общую очистку входных данных, указанную в общей (или супер) модели, а затем во-вторых, сделать несколько специальных методов, которые указаны в каждой специальной (или подклассовой) модели как def parse.

class GeneralModel(polymodel.PolyModel):
 lat_long_list = db.ListProperty(db.GeoPt)
 zooms = db.ListProperty(int)

     def __init__(self, *args, **kwargs):
  self.lat_long_list = [ db.GeoPt( pt[0] , pt[1] ) for pt in zip( kwargs["lat"] , kwargs["lon"] ) ]
  del kwargs["lat"]
  del kwargs["lon"]
  if "zooms" not in kwargs: kwargs["zooms"] = ZOOMS # some default
  for property,value in kwargs.items():
   setattr(self,property,value)
  #super(NamedModel, self).__init__(*args, **kwargs)
  self.parse()

 def parse(self):
         raise NotImplementedError('Need to define this for each category')


class SpecialModel(GeneralModel):
 stringText = db.StringProperty()
 words_list = db.StringListProperty()

 def parse( self ):
  self.words_list = self.stringText.split(",")  

Вот как я проверяю работает ли мой код:

>>>kwargs={'stringText':'boris,ted','lat':[0,1,2,3],'lon':[0,1,2,8],'zooms':[0,10]}
>>>entity=SpecialModel(key_name="tester",**kwargs)
>>>entity.words_list
['boris', 'ted']

1 Ответ

1 голос
/ 21 апреля 2010

Строка 'super' вызывает конструктор родительского объекта.Если вы не включите его, родительский конструктор не будет вызван, и ваша модель не будет правильно инициализирована.На самом деле вы должны вызывать этот сначала , прежде чем начинать какую-либо собственную инициализацию.

Однако переопределение конструктора в моделях настоятельно не рекомендуется.Конструктор используется не только при его вызове, но и системой для создания экземпляров, которые загружаются из хранилища данных, а в последнем случае аргументы - и ожидаемое поведение - отличаются и зависят от реализации.

Вместо этого вы, вероятно, должны определить фабричный метод, например, так:

class MyModel(db.PolyModel):
  @classmethod
  def create(cls, foo, bar):
    # Do some stuff
    return cls(foo, bleh)
...