Утиная типизация
Часть раздела 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 гибким и следует принципу «проще попросить прощения, чем разрешения».
Задание
СреднеВ этом испытании вы реализуете систему, демонстрирующую утиную типизацию (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")В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыПараметр selfМетодыАтрибутыМетод-конструктор (__init__)Повторение — Простой калькулятор4Наследование
Базовое наследованиеФункция super()Переопределение методовМножественное наследованиеПорядок разрешения методовИтоги — Иерархия сотрудников7Специальные методы
Введение в магические методыПерегрузка операторовМагические методы контейнеровПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy5Полиморфизм
Снова о переопределении методовУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовИтоги — Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыИтоги — Менеджер банковского счета6Инкапсуляция
Public, Protected, Private члены классаМодификаторы доступаСокрытие данныхДекораторы property: продвинутый уровеньИтоги: Система учета студентов12Проект: Управление библиотекой
Обзор проектаКлассы Book и User