Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя

Насколько нормально вызывать абстрактный метод из конструктора базового класса?

Хочу понять, попадает ли это под понятие «код с душко́м».
Есть базовый класс, у которого список параметров в конструкторе хочется оставить неизменным во всех подклассах, но в них нужно производить некоторую дополнительную инициализацию.
Принято решение вынести её в абстрактный метод, чтобы список параметров конструктора определялся только в одном месте в коде.
class Foo(ABC):
    def __init__(self, config: FooConfig):
        self.baz = Baz(config.baz_name)
        self.cfg = config
        self.setup()

    @abstractmethod
    def setup(self):
        """Переопределяемая часть."""

    # ...

class Bar(Foo):
    def setup(self):
        self.baz.add_something()

    # ...
Насколько я знаю, иногда вызов методов из конструктора считают дурным тоном, т.к. объект еще не создан.
Это код из микропроекта (фактически, скрипта), но было бы интересно услышать мнения в целом, когда такое использовать можно, когда лучше не надо, почему не надо и т.д.
ПрограммированиеPython
Георгий Устинов
Python Q
  · 4,8 K
Веб-разработчик, геймер, специалист по этике  · 19 авг 2022
У вас конструктор собирается создавать какие-то неопределённой сложности объекты самостоятельно, это воняет сильной связанностью между компонентами.
def __init__(self, config: FooConfig):
        self.baz = Baz(config.baz_name)
Я бы внедрил зависимость Baz: заставил клиентский код его создавать и снаружи в Foo передавать.
Один из авторов называет сильную связанность такого рода "принцип явных зависимостей", отличное название, на мой взгляд. 
Рекомендация делать конструкторы как можно более простыми важна в C++, потому что если какой-то код в конструкторе бросит исключение, то деструктор не будет вызван. Если конструктор к этому моменту успел занять себе какие-то ресурсы (файловые дескрипторы, порты, пайпы), всё это становится утечкой. В питоне это не так жизненно важно, потому что `init` вызывается уже после того, как объект был создан. Поэтому так сильно бояться ошибок в конструкторе, как в плюсах, на питоне не стоит, но это, конечно, не повод намеренно пихать всё подряд в конструктор.
Про то, что вы фактически реализовали паттерн шаблонного метода, вам уже сказали в другом ответе.
Вообще, конечно, сам факт того, что у вас в конструктор передаётся какой-то абстрактный Конфиг без явного доменного смысла, пованивает God Object и нарушением принципа единой ответственности, но это так часто встречается, что я лично закрываю глаза на это уже. Всех не переубедить.
Требует осмысления. Вернусь к этому позже. Вот немного контекста. Baz - это на самом деле библиотечный класс... Читать дальше
старший разработчик в pseven.io  · 11 авг 2022
То, что вы сделали — это поведенческий паттерн "Шаблонный метод". Я не встречал, чтобы его называли антипаттерном, так что проблем тут не вижу. Единственное, к чему можно придраться — это вызов дополнительной логики в конструкторе. Но тут всё зависит от реализации метода setup(). По-хорошему там не должно быть сайд-эффектов типа записи в файлы/БД, а только инициализация... Читать далее
Что-то осталось непонятно? Спроси в нашей группе в Телеграме!Перейти на t.me/jstsmentor
1 эксперт согласен
Инженер путей сообщения – строитель  · 11 авг 2022
Тут надо прежде всего понимать, как происходит создание объектов и когда вызывается конструктор. Например в языке программирования Delphi конструктор вызывается после инициализации таблицы виртуальных методов и может содержать вызовы виртуальных (и как их подвида абстрактных методов). А вот в языке С++ конструктор вызывается до инициализации таблицы, сколько виртуальных... Читать далее
1 эксперт согласен
Хочется добавить, что использование декоратора @abstractmethod как раз позволяет не забыть переопределить метод в... Читать дальше