Наследование Django: как иметь один метод для всех подклассов? [дубликат]

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

Если класс имеет более одного конструктора, я использую блок инициализации:

public class MyClass {
   private static MyFileWriter x;

   // initialization block start here
   {
       try {
          x = new MyFileWriter("..");
       } catch(Exception e) {
         // exception handling goes here
       }
   }

   public MyClass() { 
    // ctor #1
   }

   public MyClass(int n) { 
     // ctor #2
   }
}

Хорошая вещь в init. Блок заключается в том, что он «внедряется» в начало каждого конструктора. Таким образом, вам не нужно дублировать инициализаторы.

5
задан Yury Lifshits 17 October 2009 в 00:27
поделиться

3 ответа

Если вы хотите избежать проверки всех возможных подклассов, единственный способ, который я могу придумать, - это сохранить имя класса, связанное с подклассом, в поле, определенном в базовом классе . В вашем базовом классе может быть такой метод:

def resolve(self):
    module, cls_name = self.class_name.rsplit(".",1)
    module = import_module(module)
    cls = getattr(module, cls_name)
    return cls.objects.get(pk=self.pk)

Этот ответ меня не радует, и я тоже хотел бы увидеть лучшее решение, так как скоро я столкнусь с аналогичной проблемой.

2
ответ дан 15 December 2019 в 06:29
поделиться

Будете ли вы когда-нибудь работать с экземпляром базового типа или всегда будете работать с экземплярами дочерних элементов? В последнем случае вызовите метод, даже если у вас есть ссылка на базовый тип, поскольку сам объект является дочерним типом IS-A.

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

Питонический стиль программирования, который определяет тип объекта по проверка его метода или атрибута подпись, а не явная отношение к некоторому типу объекта («Если похоже на утку и крякает как утка, должно быть, утка ». подчеркивая интерфейсы, а не конкретные типы, продуманный код повышает его гибкость, позволяя полиморфная замена. Утиная печать избегает тестов с использованием type () или isinstance (). (Обратите внимание, однако, что утиная печать может быть дополнена абстрактные базовые классы.) Вместо этого обычно использует тесты hasattr () или Программирование EAFP.

Обратите внимание, что EAFP означает Проще просить прощения, чем разрешения :

Проще просить прощения, чем разрешения. Этот общий стиль кодирования Python предполагает наличие действительных ключей или атрибутов и перехватывает исключения, если предположение оказывается ложным. Этот чистый и быстрый стиль характеризуется наличием множества утверждений «попробуй и исключь». Этот метод контрастирует со стилем LBYL, общим для многих других языков, таких как C.

1
ответ дан 15 December 2019 в 06:29
поделиться

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

Это означает, что большинство наших классов определены как:

class Foo(models.Model, OurKitchenSinkClass):

По сути, это что-то вроде типа MixIn. Отлично работает, проста в обслуживании.

0
ответ дан 15 December 2019 в 06:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: