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

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

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

Хочу понять, попадает ли это под понятие «код с душко́м».
Есть базовый класс, у которого список параметров в конструкторе хочется оставить неизменным во всех подклассах, но в них нужно производить некоторую дополнительную инициализацию.
Принято решение вынести её в абстрактный метод, чтобы список параметров конструктора определялся только в одном месте в коде.
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
Инженер путей сообщения – строитель  · 11 авг 2022
Тут надо прежде всего понимать, как происходит создание объектов и когда вызывается конструктор. Например в языке программирования Delphi конструктор вызывается после инициализации таблицы виртуальных методов и может содержать вызовы виртуальных (и как их подвида абстрактных методов). А вот в языке С++ конструктор вызывается до инициализации таблицы, сколько виртуальных методов не вызывай, они все будут вызываться из базового класса, а вызов абстрактного метода будет пресечён уже на этапе компиляции.
Что же касается «душка», то все т.н. стили программирования суть кем-то придуманная вкусовщина. Кому-то показалось так удобнее/красивее вот и начали писать в книгах о личных предпочтениях, чуть ли ни как о требованиях.
С точки зрения банальной логики вызов виртуального/абстрактного метода в конструкторе базового класса не хорошо и не плохо. Если программная логика требует виртуализации на этапе создания объектов, а язык программирования это позволяет — смело вызывайте абстрактный метод. Но только учтите, что надо проконтролировать переопределение абстрактного метода во всех классах-потомках. Иначе мы будет получать потенциально плавающий конфликт доступа при выполнении нашей программы.
1 эксперт согласен
Хочется добавить, что использование декоратора @abstractmethod как раз позволяет не забыть переопределить метод в... Читать дальше
старший разработчик в pseven.io  · 11 авг 2022
То, что вы сделали — это поведенческий паттерн "Шаблонный метод". Я не встречал, чтобы его называли антипаттерном, так что проблем тут не вижу. Единственное, к чему можно придраться — это вызов дополнительной логики в конструкторе. Но тут всё зависит от реализации метода setup(). По-хорошему там не должно быть сайд-эффектов типа записи в файлы/БД, а только инициализация... Читать далее
Что-то осталось непонятно? Спроси в нашей группе в Телеграме!Перейти на t.me/jstsmentor
1 эксперт согласен
Веб-разработчик, геймер, специалист по этике  · 19 авг 2022
У вас конструктор собирается создавать какие-то неопределённой сложности объекты самостоятельно, это воняет сильной связанностью между компонентами. def __init__(self, config: FooConfig): self.baz = Baz(config.baz_name) Я бы внедрил зависимость Baz: заставил клиентский код его создавать и снаружи в Foo передавать. Один из авторов называет сильную связанность... Читать далее
Требует осмысления. Вернусь к этому позже. Вот немного контекста. Baz - это на самом деле библиотечный класс... Читать дальше