0Pricing
Python Academy · Урок

Полиморфизм и утка типизация

Пишите полиморфный код, работающий с любым совместимым объектом.

«Полиморфизм и утка типизация» — бесплатный урок Python Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

Введение

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

Что такое полиморфизм

Полиморфизм означает «много форм». Одно и то же имя метода по-разному работает с разными объектами. Python активно использует этот принцип.
class Cat:
    def speak(self): return 'Meow'
class Dog:
    def speak(self): return 'Woof'
for animal in [Cat(), Dog()]:
    print(animal.speak())

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

Для полиморфизма Python не требует иерархии классов. Если у объекта есть нужный метод, он работает. Интерфейсы не нужны.
class Duck:
    def quack(self): return 'Quack'
class Person:
    def quack(self): return 'I am quacking like a duck'
def make_it_quack(duck):
    print(duck.quack())
make_it_quack(Duck())
make_it_quack(Person())

Полиморфные функции

len() работает со строками, списками, словарями и кортежами — всё потому, что они реализуют __len__. Это встроенный полиморфизм.
for obj in ['hello', [1,2,3], {'a':1}]:
    print(type(obj).__name__, len(obj))

Перегрузка операторов

Оператор + работает с целыми числами, числами с плавающей точкой, строками и списками, поскольку каждый из этих типов по-разному реализует __add__.
print(1 + 2)        # int addition
print('a' + 'b')    # string concat
print([1] + [2])    # list concat

Утиная типизация на основе протокола

Протокол итерации: любой объект с __iter__ и __next__ работает в циклах for — базовый класс не нужен.
class Squares:
    def __init__(self, n): self.n,self.i=n,0
    def __iter__(self): return self
    def __next__(self):
        if self.i>=self.n: raise StopIteration
        x=self.i**2; self.i+=1; return x
print(list(Squares(5)))

EAFP и LBYL

EAFP (проще попросить прощения, чем разрешения) использует try/except. LBYL (сначала проверьте, прежде чем действовать) использует if/hasattr. Python предпочитает EAFP.
# LBYL:
if hasattr(obj, 'quack'):
    obj.quack()
# EAFP (Pythonic):
try:
    'hello'.quack()
except AttributeError:
    print('no quack')

isinstance() для безопасного выбора поведения

Когда требуется поведение, зависящее от типа, isinstance() лучше, чем перехват AttributeError.
def process(data):
    if isinstance(data, str):
        return data.upper()
    elif isinstance(data, list):
        return [x*2 for x in data]
print(process('hi'))
print(process([1,2,3]))

Абстрактные базовые классы как протоколы

from abc import ABC, abstractmethod определяет формальные протоколы. Подклассы должны реализовать абстрактные методы.
from abc import ABC, abstractmethod
class Drawable(ABC):
    @abstractmethod
    def draw(self): pass
class Circle(Drawable):
    def draw(self): print('O')
Circle().draw()

typing.Protocol (3.8+)

class MyProtocol(Protocol): определяет структурную типизацию без ABC. Это работает с mypy для статических проверок.
from typing import Protocol
class Quackable(Protocol):
    def quack(self) -> str: ...
def make_quack(x: Quackable) -> str:
    return x.quack()
print('protocol demo')

Полиморфизм на практике

Проектируйте API, принимающие любой объект с нужным интерфейсом. Это делает код расширяемым без внесения изменений.
class JSONSerializer:
    def serialize(self, obj): import json; return json.dumps(obj)
class XMLSerializer:
    def serialize(self, obj): return f'<data>{obj}</data>'
def export(data, serializer):
    return serializer.serialize(data)
print(export({'x': 1}, JSONSerializer()))

Быстрая проверка

Что означает утиная типизация в Python?

Итоги

Полиморфизм: один и тот же интерфейс, разное поведение. Утиная типизация: важно поведение, а не тип. Протоколы неформально определяют интерфейсы. EAFP (try/except) — характерный для Python подход.

Продолжайте

Отличный прогресс! Продолжайте, чтобы освоить следующую концепцию.

Часто задаваемые вопросы

Урок «Полиморфизм и утка типизация» бесплатный?

Да — полный текст урока «Полиморфизм и утка типизация» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «Полиморфизм и утка типизация»?

Пишите полиморфный код, работающий с любым совместимым объектом. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Полиморфизм и утка типизация»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Одиночное наследование
  2. Переопределение методов и super()
  3. Множественное наследование и MRO
  4. Полиморфизм и утка типизация
← Назад к Python Academy