Menu
Coddy logo textTech

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

Часть раздела Object Oriented Programming путешествия по 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

Задание

Средне

В этом испытании вы реализуете систему, демонстрирующую утиную типизацию (duck typing) с различными файлоподобными объектами:

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

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

Шпаргалка

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

Пример утиной типизации с несвязанными классами, которые имеют одинаковые методы:

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!"

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

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

# Работает с любым объектом, у которого есть методы swim() и quack()
make_it_swim_and_quack(Duck())
make_it_swim_and_quack(Person())

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

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

# 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


# Test with different data sources - DO NOT MODIFY THIS TEST CODE
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Проверьте себя

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

Все уроки раздела Object Oriented Programming