Что такое duck typing и динамическая типизация в Python
Что проверяют
Различаете ли вы две независимые оси: когда проверяются типы, во время выполнения или до него, и по какому признаку объект считается подходящим, по поведению или по объявленному классу. Заодно смотрят, знаете ли, что современная типизация в Python не отменяет утиную, а формализует её.
Как отвечать
Динамическая типизация означает, что тип принадлежит объекту, а не переменной, и проверяется в момент операции. При этом Python типизирован строго: неявных приведений между строкой и числом нет, выражение 1 + "1" падает. Пары динамическая или статическая и строгая или слабая независимы, и смешивать их не стоит.
Утиная типизация следует отсюда: функции важно, что объект умеет, а не от кого он унаследован. Есть метод read, значит объект годится туда, где читают, независимо от класса. Отсюда же стиль, который в сообществе называют EAFP: пробуем операцию и обрабатываем исключение, а не проверяем тип заранее.
def render(stream):
try:
data = stream.read()
except AttributeError as exc:
raise TypeError("нужен объект с методом read") from excСтатическая сторона вопроса: typing.Protocol описывает требуемый набор методов, а проверяющий инструмент вроде mypy сверяет соответствие до запуска и не требует наследования. Это та же утиная типизация, только проверяемая заранее.
Где спотыкаются
Называют Python слабо типизированным, путая динамику со слабостью. Слабая типизация это неявные приведения, знакомые по JavaScript, где число молча склеивается со строкой. В Python таких приведений нет, и ошибка типа вылезает явным исключением.
Расставляют проверки isinstance ради дисциплины и ломают ровно то, ради чего язык выбирали. Функция перестаёт принимать подходящие объекты: обёртки, подменённые в тестах заглушки, свои потокоподобные классы. Если контракт хочется зафиксировать явно, ему место в протоколе, а не в цепочке проверок класса.
Ждут, что аннотации проверяются во время выполнения. Интерпретатор их как проверки не исполняет, поэтому неверный тип всплывёт позже и не там, где ошибка. Польза от аннотаций появляется, только когда проверяющий инструмент запущен в конвейере сборки.