Зарегистрируйтесь, чтобы продолжить обучение

Диспетчеризация по ключу (функции) Python: Полиморфизм

Диспетчеризацию по ключу используют и для работы с функциями. В Python функции являются объектами первого класса, поэтому их можно присвоить переменным, сохранить в структурах данных и передать или вернуть из других функций. Это позволяет использовать функции как значения в словарях и выбирать, какую функцию вызвать на основе ключа.

Вместо создания длинных и сложных последовательностей условных операторов if-elif-else, можно обратиться к словарю и использовать заранее связанные функции для определенных ключей. Такой подход упрощает выбор правильной функции для выполнения, что приводит к созданию более чистого, понятного и управляемого кода.

От условной логики к диспетчеризации по ключу

Представим, что нам нужно поприветствовать пользователя на разных языках. Для этого реализуем код с помощью if-elif-else:

def greet_in_english(name):
    return f"Hello, {name}!"


def greet_in_french(name):
    return f"Bonjour, {name}!"


def greet_in_spanish(name):
    return f"Hola, {name}!"


def greet(language, name):
    if language == "english":
        return greet_in_english(name)
    elif language == "french":
        return greet_in_french(name)
    elif language == "spanish":
        return greet_in_spanish(name)
    else:
        return "Error: Invalid language"


print(greet("english", "Alice"))  # => Hello, Alice!
print(greet("french", "Bob"))  # => Bonjour, Bob!
print(greet("spanish", "Charlie"))  # => Hola, Charlie!
print(greet("german", "David"))  # => Error: Invalid language

В этом коде у нас три функции приветствия пользователя на разных языках. Также есть функция greet, которая использует конструкцию if-elif-else для определения, на каком языке следует приветствовать пользователя.

По мере увеличения количества поддерживаемых языков данный код станет трудным для поддержки и расширения. Для каждого нового языка нужно добавлять новое условие в функцию greet. В таких случаях стоит использовать диспетчеризацию по ключу.

Вместо использования блока if-elif-else, можно использовать словарь. В этом случае ключами будут языки, а значениями — функции, которые выводят приветствие на соответствующем языке:

def greet_in_english(name):
    return f"Hello, {name}!"


def greet_in_french(name):
    return f"Bonjour, {name}!"


def greet_in_spanish(name):
    return f"Hola, {name}!"


def error_message(*args, **kwargs):
    return "Error: Invalid language"


greetings = {
    "english": greet_in_english,
    "french": greet_in_french,
    "spanish": greet_in_spanish,
}


def greet(language, name):
    func = greetings.get(language, error_message)
    return func(name)


print(greet("english", "Alice"))  # => Hello, Alice!
print(greet("french", "Bob"))  # => Bonjour, Bob!
print(greet("spanish", "Charlie"))  # => Hola, Charlie!
print(greet("german", "David"))  # => Error: Invalid language

Этот код делает то же самое, что и предыдущий, но иначе. Вместо if-elif-else для выбора функции приветствия, мы используем словарь. Затем мы используем метод get словаря, чтобы получить функцию приветствия для данного языка. Если функция приветствия для языка не найдена, мы возвращаем функцию по умолчанию, в нашем случае — error_message.

У этого кода те же функциональные возможности, что и у версии с if-elif-else, но его легче поддерживать и расширять. Если мы хотим добавить новый язык, необходимо добавить новую пару ключ-значение в словарь greetings. При этом не нужно изменять логику функции greet.

Это делает код более модульным и гибким. Данный подход также облегчает тестирование и отладку, поскольку каждую операцию можно тестировать и отлаживать независимо.

Выводы

Диспетчеризация по ключу — мощный инструмент, который делает код более читаемым, модульным и гибким. Когда мы применяем его к функциям, мы можем создавать словари. В этом случае ключи соответствуют различным условиям или сценариям, а значения — это функции, которые будут выполняться для этих условий.

Вместо длинных и запутанных цепочек if-elif-else можно обращаться к словарю и использовать функции, которые уже связаны с определенными ключами. Это упрощает выбор правильной функции для выполнения и делает код более наглядным.

Еще диспетчеризация по ключу упрощает расширение функциональности кода. Если нам нужно добавить новое поведение, мы можем просто добавить новую пару ключ-значение в наш словарь. При этом нам не нужно трогать основную логику программы. Это делает код более устойчивым к изменениям и облегчает его поддержку.

В итоге диспетчеризация по ключу — это подход, который помогает нам писать более чистый, понятный и управляемый код.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff