Реализация метода в наследниках или просто несколько функций?

Предположим, есть какая-то функциональность, для которой можно создать несколько реализаций. Для примера пусть будет анализ текста. И есть какой-то код, которому эта функциональность нужна, т.е. что-то типа:

def use_case():
    # preprocessing
    result = analyze_text(some_text)
    # post processing

Реализовать этот анализ текста можно по-разному, и я хочу понять, какой подход лучше, и почему:

Вариант 1. Интерфейс и классы с фактической реализацией. Т.е. что-то типа:

class TextAnalyzer:
    def analyze(self, text):
        raise NotImplementedError

class Analyzer1(TextAnalyzer):
    def analyze(self, text):
        # implementation 1
        ...

class Analyzer2(TextAnalyzer):
    def analyze(self, text):
        # implementation 2
        ...

и тогда вызывающий код будет создавать (или откуда-то получать) объект analyzer = Analyzer1() и вызывать analyzer.analyze(some_text)

Вариант 2. Просто несколько функций с разными реализациями. Т.е. что-то типа:

def analyze1():
    # implementation 1
    ...

def analyze2():
    # implementation 2
    ...

вызывающий код опять-таки может сам просто в нужном месте вызывать analyze1(), или же получать откуда-то объект функции analyze_function = analyze1 и потом уже его вызывать.

Какой вариант более предпочтителен и более питоновский и почему?

P.S.

Я долгое время писал на java, поэтому мне ближе подход с созданием интерфейса и реализацией в подклассах, но сейчас, думая о преимуществах такого подхода, я не могу найти каких-то серьёзных пунктов За и Против кроме, быть может, проверки типов, но я не уверен, возможно для функций это тоже осуществимо


Ответы (0 шт):