У вас конструктор собирается создавать какие-то неопределённой сложности объекты самостоятельно, это воняет сильной связанностью между компонентами.
def __init__(self, config: FooConfig):
self.baz = Baz(config.baz_name)
Я бы внедрил зависимость Baz: заставил клиентский код его создавать и снаружи в Foo передавать.
Рекомендация делать конструкторы как можно более простыми важна в C++, потому что если какой-то код в конструкторе бросит исключение, то деструктор не будет вызван. Если конструктор к этому моменту успел занять себе какие-то ресурсы (файловые дескрипторы, порты, пайпы), всё это становится утечкой. В питоне это не так жизненно важно,
потому что `init` вызывается уже после того, как объект был создан. Поэтому
так сильно бояться ошибок в конструкторе, как в плюсах, на питоне не стоит, но это, конечно, не повод намеренно пихать всё подряд в конструктор.
Про то, что вы фактически реализовали паттерн шаблонного метода, вам уже сказали в другом ответе.
Вообще, конечно, сам факт того, что у вас в конструктор передаётся какой-то абстрактный Конфиг без явного доменного смысла, пованивает God Object и нарушением принципа единой ответственности, но это так часто встречается, что я лично закрываю глаза на это уже. Всех не переубедить.