Есть несколько базовых классов:
# base.py
class BaseParser:
_SOURCE = NotImplemented
def parse():
print(f'base from {self.source}')
class FooBaseParser:
_SOURCE = NotImplemented
def parse():
print(f'foo from {self.source}')
Так же несколько рабочих классов, обычно выглядящие так:
# module parser_a.py
class AParser(BaseParser):
_SOURCE = 'aaa.aaa'
# module parser_b.py
class BParser(BaseParser):
_SOURCE = 'bbb.bbb'
# module parser_c.py
class CParser(FooBaseParser):
_SOURCE = 'ccc.ccc'
и модули которые работают с парсерами, например:
# work_a.py
class AWork:
_PARSER = AParser
def work():
parser = self._PARSER()
parser.parse()
Теперь нужно реализовать выбор базового парсера для каждого из рабочих в зависимости от условия, я это пока вижу так (работа с модулями строгая):
Возможно можно использовать какой-нибудь паттерн проектирования, только я не разобрался какой
# base.py
class ParserSelector:
def __init__(self, foo, *args, **kwargs):
self.init = foo, args, kwargs
def get_parser(foo):
return FooBaseParser if foo else BaseParser
def parse():
foo, args, kwargs = self.init
parser = self.get_parser(foo)
return parser(*args, **kwargs).parse()
Рабочие парсеры:
# parser_a.py
class AParser(ParserSelector):
_SOURCE = 'aaa.aaa'
# parser_c.py
class CParser(ParserSelector):
_SOURCE = 'ccc.ccc'
# work_a.py
class AWork:
_PARSER = AParser
def work():
parser = self._PARSER(foo=False)
parser.parse() #prints 'bar from aaa.aaa'
# work_c.py
class CWork:
_PARSER = CParser
def work():
parser = self._PARSER(foo=True)
parser.parse() #prints 'foo from ccc.ccc'
в данном случае остается проблема, что переопределенный атрибут класса SOURCE не пробрасывается до базовых классов. Место, где его можно найти это в self у ParserSelector'a. Так как можно пробросить атрибуты класса в базовый не прибегая к переопределению каждого атрибута экземпляра где-нибудь в init'e базового, так как их достаточно много
Чтобы не было так:
class BaseParser:
_SOURCE = NotImplemented
def __init__(self, child_self):
self._SOURCE = child_self._SOURCE