Если вы создаёте новые объекты внутри метода __init__, возможно, будет лучше передавать их как аргументы и использовать фабричный метод.
В этом примере __init__ принимает host и port для создания подключения к базе данных:
class Query:
def __init__(self, host, port):
self._connection = Connection(host, port)
Возможный рефакторинг:
class Query:
def __init__(self, connection):
self._connection = connection
@classmethod
def create(cls, host, port):
return cls(Connection(host, port))
Такой подход имеет как минимум следующие преимущества:
• Упрощает внедрение зависимостей. В тестах можно использовать Query(FakeConnection()).
• Класс может иметь столько фабричных методов, сколько нужно; подключение может создаваться не только по host и port, но и путём клонирования другого подключения, чтения конфигурационного файла или объекта, использования значения по умолчанию и т.д.
• Такие фабричные методы можно сделать асинхронными; это невозможно для __init__.
👉 @BookPython