+--------------------------+
|.------------------------.|
|| kee_reel@blog:~$ cd    ||
|| си python терминал     ||
|| opengl sql             ||
||                        ||
||                обо_мне ||
|.------------------------.|
+-::--------------------::-+
.--------------------------.
 // /ooooooooooooooooooooo\\ \\ 
 // /ooooooooooooooooooooooo\\ \\ 
//------------------------------\\
\\------------------------------//

Python. Полиморфизм

Эта статья является составной частью статьи про ООП – если ты хочешь понять всю картину, то лучше начать с неё.

Полиморфизм в классах

Полиморфизм – позволяет единообразно работать с методами разных классов, наследованных от одного родительского класса.

Объясняю на примере – перед тобой стоит три машины с коробкой-автоматом от разных производителей:

class Car:
    def __init__(self, manufacturer, horse_powers):
        def._manufacturer = manufacturer
        self._horse_powers = horse_powers

    def turn_on(self):
        print(f'Ты запустил двигатель у {def._manufacturer}, мощность которой {self._horse_powers} лошадиных сил')


class Xonda(Car):
    def __init__(self):
        Car.__init__(self, 'Xonda', 180)


class Xoyota(Car):
    def __init__(self):
        Car.__init__(self, 'Xoyota', 200)


class XMW(Car):
    def __init__(self):
        Car.__init__(self, 'XMW', 220)

Если тебе завяжут глаза, и посадят как любую из этих машин, то у тебя получится её завести:

import random

cars = [Xonda(), Xoyota(), XMW()]
car = random.choice(cars)
car.turn_on()
# Вывод:
# Ты запустил двигатель у Xoyota, мощность которой 200 лошадиных сил

Функция choice() выбирает случайный элемент из списка/кортежа/словаря.

А ещё ты можешь залезть в каждую машину, и запустить её:

cars = [Xonda(), Xoyota(), XMW()]
for car in cars:
    car.turn_on()
# Вывод:
# Ты запустил двигатель у Xonda, мощность которой 180 лошадиных сил
# Ты запустил двигатель у Xoyota, мощность которой 200 лошадиных сил
# Ты запустил двигатель у XMW, мощность которой 220 лошадиных сил

То есть полиморфизм позволяет тебе работать одинаково с объектами, которые наследуются от одного класса.

Однако, кроме одисанного случая, можно выделить ещё один – полиморфизм в функциях и методах.

Полиморфизм в функциях и методах

Полиморфизм – позволяет передавать функцию параметры разных типов, но получать одинаковое поведение.

Ты пришёл в библиотеку будущего и хочешь взять книгу “Введение в программирование”. Там стоит терминал, в который надо ввести название:

book_names = {
    'Введение в программирование': 'https://link-to-download-1',
    'Язык Си для чайников': 'https://link-to-download-2',
    'Компьютерные сети': 'https://link-to-download-3',
    'Нейромант': 'https://link-to-download-4'
}

def download_book(link):
    # Тут как-будто логика загрузки книги с файлового сервера библиотеки
    return 'book-text'


def book_terminal(input_data):
    if input_data in books:
        link = books[input_data]
        return download_book(link)
    return None # Книга не найдена

Ты вводишь название книги, получаешь место, забираешь её и уходишь.

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

Нужно изменить функцию book_terminal() так, чтобы она могла принимать как строковые названия книг, так и их численные ID. Вот как это можно сделать:

book_name_to_id = {
    'Введение в программирование': 6127459,
    'Язык Си для чайников': 9163713,
    'Компьютерные сети': 6046931,
    'Нейромант': 2103971
}
book_id_to_link = {
    6127459: 'https://library.link-to-download-programming.com',
    9163713: 'https://library.link-to-download-c-language.com',
    6046931: 'https://library.link-to-download-networks.com',
    2103971: 'https://library.link-to-download-neuromant.com'
}

def download_book(link):
    # Тут как-будто логика загрузки книги с файлового сервера библиотеки
    return f'Text of book {link}'


def book_terminal(input_data):
    if isinstance(input_data, str): # Новая для тебя функция isinstance(), описание ниже
        book_id = book_name_to_id.get(input_data, None)  # Новый для тебя метод get(), описание ниже
        if book_id is None:
            return None
    else:
        book_id = input_data
    link = book_id_to_link.get(book_id, None)
    if link is not None:
        return download_book(link)
    return None # Книга не найдена

isinstance() это стандартная функция, которая позволяет проверить к какому типу принадлежит значение. Первый аргумент это значение, которое надо проверить, а второй это тип – если значение принадлежит этому типу, то вернётся True.

У dict есть метод get(), который принимает два аргумента. Первый аргумент это ключ, по которому надо найти значение, а второй это значение, которое надо вернуть если такого ключа нет.

Теперь, терминалом может пользоваться как человек, передавая строку:

book_terminal('Нейромант')
# Вывод:
# Text of book https://library.com/link-to-download-neuromant

Так и осознавший себя искусственный интеллект, передавая численный ID:

for book_id in book_id_to_link:
    print(book_terminal(book_id))
# Вывод:
# Text of book https://library.com/link-to-download-programming
# Text of book https://library.com/link-to-download-c-language
# Text of book https://library.com/link-to-download-networks
# Text of book https://library.com/link-to-download-neuromant

Ты скорее всего уже пользовался полиморфизмом функций:

print( len([1,2,3,4,5,6]) ) # Вывод: 6
print( len('some_word') ) # Вывод: 9

Стандартная функция len() тоже может принимать разные типы данных, и возвращать одинаковый результат.

Всё, что здесь сказано про функции, справедливо так же и для методов – ведь они такие же функции, но описанные в классе.

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

Заключение

Итого, мы изучили:

  • Полиморфизм классов (одинаковый метод у разных классов)
  • Функция choice из библиотеки random (выбирает случайный элемент из списка списка/кортежа/словаря)
  • Полиморфизм функций (разные типы параметров)
  • Функция isinstance() (проверить тип значения)
  • Метод get() (вернуть значение по умолчанию если такого ключа нет)

Если что – пиши, я помогу и постараюсь объяснить лучше.

Если ты ещё полон сил, то вернись к статье про ООП, и продолжи постижение ООП.