Питон, оверинг сам - PullRequest
       7

Питон, оверинг сам

0 голосов
/ 11 октября 2011

У меня следующая проблема.У меня есть модель класса в MVC, и у него есть специальное назначение.В некоторых случаях он должен иметь возможность переопределить себя.Возможно ли такое поведение?

Class Text(Document):
    a =  StringField()
    b =  StringField()

    def save(self):
        if 1==Text.object(a=self.a).count():       # if similar object exists in db,
             self = Text.object(a=self.a).first()  # get the instance from db and
                                                   # override the origian class.
        else:                                      #use super class' save-function
             return super(Text, self).save()

Ответы [ 2 ]

1 голос
/ 12 октября 2011

Нет простого способа для стать другим объектом в python. Назначение self не сделает этого; self - это локальная переменная в определении метода, и ее присвоение никак не изменит существующий экземпляр; только сделать его недоступным для остальной части метода.

Есть несколько способов решения этой проблемы. Предпочтительным способом является наличие метода, который возвращает правильный экземпляр.

class Foo(...):
    def get_or_save(self):
        existing = load_from_database(self.bar)
        if existing is not None:
            return existing
        else:
            save_to_database(self)
            return self

new_inst = Text()
new_inst.bar = "baz"

inst = new_inst.get_or_save()
# stop using new_inst

Существует также хакерский способ получить эффект, подобный вашему первоначальному примеру. Обычные классы Python хранят большинство своих атрибутов в специальном атрибуте __dict__. Вы можете скопировать это, и будет, как будто один экземпляр заменяется другим. Конечно, это работает только для совершенно простых классов Python и может работать, а может и не работать с классами, определенными в ORM, или которые сохраняют состояние более умными способами.

class Foo(...):
    def save(self):
        existing = load_from_database(self.bar)
        if existing is not None:
            self.__dict__ = existing.__dict__
        else:
            save_to_database(self)
0 голосов
/ 11 октября 2011

Да, это возможно: -)

Серьезно, использование условного вызова super, как в вашем примере, приведет к результату.

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

  1. Я бы не рекомендовал помещать в ваш класс метод с именем object, если у меня не было другого выбора.
  2. Тот факт, чтовы передаете self.a в Text.object, в методе Text.save, это не так.Было бы чище просто вызвать self.object() и иметь метод object, использующий self.a непосредственно в своем коде.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...