Мои извинения за то, что может быть базовым c вопросом. Я программист на C ++, который относительно новичок в python.
У меня есть класс python, поведение которого существенно зависит от одного из аргументов его конструктора:
class MyClass():
def __init__(self, some_arg):
self.some_arg = some_arg
...
def abcd(self):
if self.some_arg == 1:
...
else:
...
def efgh(self):
if self.some_arg == 1:
...
else:
...
Я бы Я хотел бы реорганизовать это в два класса с разными значениями some_arg. Конечно, наиболее простой вещью было бы иметь два класса (возможно, с общим базовым классом) и затем иметь фабричную функцию, выбирающую, какой из них создать. Что-то вроде:
def MyClassSomeArg1():
def __init__(self):
...
def abcd(self):
...
def efgh(self):
...
def MyClassSomeArgNot1():
def __init__(self):
...
def abcd(self):
...
def efgh(self):
...
def buildMyClass(some_arg):
if some_arg == 1:
return MyClassSomeArg1()
else:
return MyClassSomeArgNot1()
Я уверен, что это будет работать нормально. Проблема в том, что я не хочу менять код клиента. Клиенты ожидают создания экземпляра объекта класса «MyClass» с аргументом конструктора some_arg. Есть ли достойный способ реорганизовать это под капотом без изменения клиентского кода?
Я попытался использовать иерархию реализации: MyClassImpl в качестве базового класса с подклассами MyClassImplSomeArg1 и MyClassImplSomeArgNot1. MyClass сам тогда становится в основном пустым:
class MyClass():
def __init__(self, some_arg):
if some_arg == 1:
self._impl = MyClassImplSomeArg1()
else:
self._impl = MyClassImplSomeArgNone1()
def __getattr__(self, a):
# For performance, I could store this in self so it doesn't need to be looked up each time
return getattr(self._impl, a)
Это в основном работает, но это не самая простая вещь. С одной стороны, методы magi c, такие как __str__ и __eq__, похоже, не делегируются через механизм __getattr__, и я не знаю почему. Хотя написать методы делегирования не сложно. Кроме того, это сбивает с толку pydo c (он не может видеть делегированные атрибуты), и я не уверен, как это исправить.
Есть ли сахар, чтобы эта схема делегирования работала хорошо? Или делегирование - даже лучший способ справиться с такой проблемой?
Спасибо,