У меня есть базовый класс Base
и два подкласса Foo
и Bar
. В Base
я определяю функцию с необязательным аргументом. Этот аргумент либо задается, либо извлекается во время выполнения (не во время определения). Аргумент всегда извлекается одним и тем же способом, что приводит к тому, что подклассы имеют шаблонную строку кода (конечно, это одна строка, но это просто пример). Обычно это выглядело бы так:
class Base(object):
def greet(self, name=None):
pass
class Foo(Base):
def greet(self, name=None):
name = name or get_name_at_runtime()
print('Hello {name} this is Foo.'.format(name=name))
class Bar(Base):
def greet(self, name=None):
name = name or get_name_at_runtime()
print('Hello {name} this is Bar.'.format(name=name))
Теперь я придумал хак, который решает эту проблему, но я не считаю это надежным решением. Решение включает в себя определение частного метода, который обертывает переопределенный метод и предоставляет ему правильное значение. Оба метода переключаются в __init__
, поэтому вызов/переопределение метода кажется «нормальным»:
class Base(object):
def __init__(self):
self.greet, self.__greet = self.__greet, self.greet
def greet(self, name):
pass
def __greet(self, name=None):
self.__greet(name or get_name_at_runtime())
class Foo(Base):
def greet(self, name):
print('Hello {name} this is Foo.'.format(name=name))
class Bar(Base):
def greet(self, name):
print('Hello {name} this is Bar.'.format(name=name))
«Решение», которое я придумал, создает проблему, заключающуюся в том, что неясно, является ли имя необязательным, поскольку похоже, что оно не имеет значения по умолчанию.
В некоторых случаях Base
является абстрактным базовым классом, а в некоторых — нет, поэтому я ищу решение, поддерживающее оба варианта.