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

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

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

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

Понимание динамической диспетчеризации

По функциям всегда можно сказать, где они определены. Для этого нужно посмотреть на модули, из которых их импортировали.

С методами все сложнее. Когда мы видим вызов метода, нельзя сразу сказать, откуда он пришел. Это зависит от типа объекта, у которого он вызван. Полиморфизм подразумевает подмену объектов, а значит одна и та же строчка кода может вызывать разные методы (но имеющие одинаковые имена), в зависимости от пришедшего объекта.

Полиморфизм в Python реализуется с помощью динамической диспетчеризации. Это механизм, который занимается выбором необходимой реализации метода.

Рассмотрим следующий пример:

def print_name(obj):
    print(obj.get_name())


print_name(User({"name": "Mike"}))

Здесь показана функция, которая ожидает, что на вход ей передается объект с методом get_name() и печатает его на экран.

Технически этот код можно представить так:

class User:
    def __init__(self, data):
        self.name = data["name"]

    def get_name(self):
        return self.name


def print_name(obj):
    print(obj.get_name())


print_name(User({"name": "Mike"}))

В этом примере User({'name': 'Mike'}) создает объект. В Python вызов метода запускает механизм диспетчеризации, который определяет класс данного объекта, затем проверяет список методов этого класса и ищет среди них get_name().

Работа диспетчера

Разберем, что происходит при вызове метода:

class User:
    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name


def call_method(self, method_name, *args):
    methods = getattr(self, "__class__").__dict__
    method = methods.get(method_name)
    if method:
        return method(self, *args)
    raise Exception("No method error")


call_method(User("Mike"), "get_name")

Этот код содержит три важные детали:

  1. Методы — это логическое понятие. Внутри языка это обычные функции
  2. Список классов и методов хранится в структуре данных, называемой словарем
  3. obj — это исходный объект, который передается первым параметром. Мы получили его, когда делали User({'name': 'Mike'})

Важно отметить, что в Python self является явным аргументом для методов. Это отличительная черта Python по сравнению с некоторыми другими языками, такими как PHP.

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

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

Выводы

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

Знание этой концепции полезно для написания более эффективного и надежного кода, особенно при решении более сложных задач ООП.


Дополнительные материалы

  1. Мультидиспетчеризация

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

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

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

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

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

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

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

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