Глава 14 · Создаём объекты реального мира

Duck typing

Python не проверяет, от какого класса унаследован объект — только то, есть ли у него нужный метод.

«Если это выглядит как утка и крякает как утка...»

В разделе 14.18 все классы разделяли общего родителя не всегда. На самом деле Python вообще не проверяет, от какого класса объект унаследован, чтобы вызвать метод — важно только, ЕСТЬ ли у объекта нужный метод:

duck_typing.py
class Sobaka:                    # никак не связана с Robot
    def predstavitsya(self):
        print("Гав! Я собака.")


class Robot:                     # никак не связана с Sobaka
    def predstavitsya(self):
        print("БИП. Я робот.")


def poznakomit(obj):
    obj.predstavitsya()   # неважно, какого obj класса — важно, что метод есть

poznakomit(Sobaka())
poznakomit(Robot())
Частое заблуждение: «полиморфизм требует наследования»
Это не так, и duck typing — прямое тому доказательство. Sobaka и Robot НЕ имеют общего родителя (кроме неявного object), но poznakomit() одинаково успешно работает с обоими. В Python интерфейс — это фактическое наличие нужного метода, а не формальная запись в дереве наследования.

Название пришло из выражения «если оно выглядит как утка, плавает как утка и крякает как утка — вероятно, это и есть утка»: неважно, как объект был создан, важно, что он УМЕЕТ.

Debug Lab 11: не у всех объектов в списке есть ожидаемый метод
nesovmestimyj_obekt.py
zhivotnye = [Sobaka(), Robot(), "просто строка"]
for zh in zhivotnye:
    zh.predstavitsya()
Гав! Я собака.
БИП. Я робот.
Traceback (most recent call last):
AttributeError: 'str' object has no attribute 'predstavitsya'
Что видно на экране

Duck typing не проверяет наличие метода заранее — Python просто пытается вызвать predstavitsya() и падает в момент вызова, если метода нет. Гибкость duck typing не отменяет ответственность: класть в один список объекты, которые ДОЛЖНЫ поддерживать общий метод, нужно осознанно.

Исправленный код
s_proverkoj.py
for zh in zhivotnye:
    if hasattr(zh, "predstavitsya"):
        zh.predstavitsya()
Практика: duck typing
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →