Menu
CoddyTech

Утиная типизация

Часть раздела Объектно-ориентированное программирование путешествия по Python на Coddy. Урок 24 из 64.

Утиная типизация фокусируется на том, что объект может делать, а не на том, чем он является. Если у объекта есть нужные вам методы, вы можете его использовать — независимо от его типа класса.

Вот два не связанных друг с другом класса с одинаковыми методами:

class Duck:
    def swim(self):
        return "Duck swimming"
    
    def quack(self):
        return "Quack!"

class Person:
    def swim(self):
        return "Person swimming"
    
    def quack(self):
        return "Person imitating a duck: Quack!"

Обрати внимание, что Duck и Person не наследуются от одного и того же родительского класса, но у них обоих есть методы swim() и quack().

Создай функцию, которая работает с любым объектом, «похожим на утку»:

def make_it_swim_and_quack(duck_like_object):
    print(duck_like_object.swim())
    print(duck_like_object.quack())

Этой функции не важен тип объекта — важно лишь, чтобы у объекта были необходимые методы.

Используй функцию с обоими классами:

make_it_swim_and_quack(Duck())
make_it_swim_and_quack(Person())

Вывод:

Duck swimming
Quack!
Person swimming
Person imitating a duck: Quack!

Добавь ещё один класс «похожий на утку»:

class Robot:
    def swim(self):
        return "Robot swimming with propellers"
    
    def quack(self):
        return "Robot sound: BEEP BEEP!"

make_it_swim_and_quack(Robot())

Вывод:

Robot swimming with propellers
Robot sound: BEEP BEEP!

Ключевой момент: утиная типизация позволяет использовать полиморфизм без наследования. Если у объекта есть нужные вам методы, вы можете его использовать. Благодаря этому код Python становится гибким, что соответствует принципу «проще попросить прощения, чем разрешения».

challenge icon

Задание

Средне

В этом задании ты реализуешь систему, демонстрирующую утиный тип с различными объектами, похожими на файлы:

  • textfile.py: реализуй класс TextFile с методами read() и write(data)
  • database.py: реализуй класс Database с соответствующими сигнатурами методов
  • networkresource.py: реализуй класс NetworkResource с соответствующими сигнатурами методов
  • driver.py — реализуй тестовые случаи, которые проверят, правильно ли работает твоя реализация

В каждом файле есть подробные комментарии TODO, которые помогут тебе с реализацией.

Попробуйте сами

# TODO: Импортируйте класс TextFile из textfile.py
# TODO: Импортируйте класс Database из database.py
# TODO: Импортируйте класс NetworkResource из networkresource.py

def process_data(data_source, data):
    # TODO: Вызовите метод read() у data_source и выведите результат
    # TODO: Вызовите метод write(data) у data_source и выведите результат
    pass


# Тестирование с разными источниками данных — НЕ ИЗМЕНЯЙТЕ ЭТОТ ТЕСТОВЫЙ КОД
text_file = TextFile()
database = Database()
network = NetworkResource()

print("Processing text file:")
process_data(text_file, "Hello, world!")

print("\
Processing database:")
process_data(database, "User record")

print("\
Processing network resource:")
process_data(network, "GET request")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Python