Утиная печать не сводится к проверке наличия необходимых вещей и их использованию. Утиная печать - это просто использование того, что вам нужно.
Функция in_the_forest
была написана разработчиком, который думал об утках. Он был разработан для работы на Duck
. A Duck
может quack
и feathers
, поэтому кодер использовал эти функции, чтобы выполнить работу под рукой. В этом случае тот факт, что Duck
может также swim
не использовался и не был необходим.
В статическом языке, таком как Java, было бы объявлено, что in_the_forest
принимает Duck
. Когда позже кодер обнаружил, что у них есть Person
(который также может quack
и feathers
), и он хочет повторно использовать функцию, им не повезло. Является ли Person
подклассом Duck
? Нет, это не совсем уместно. Есть ли QuacksAndFeathers
интерфейс? Может быть, если нам повезет. В противном случае нам нужно будет сделать один, изменить Duck
, чтобы реализовать его, и изменить in_the_forest
, чтобы взять QuacksAndFeathers
вместо Duck
. Это может быть невозможно, если Duck
находится во внешней библиотеке.
В Python вы просто передаете свою персону на in_the_forest
, и это работает. Поскольку оказывается, что in_the_forest
не нужен Duck
, ему просто нужен "подобный утке" объект, и в этом случае Person достаточно похож на утку.
game
хотя, требуется другое определение "утиный", которое немного сильнее. Здесь Джону Смиту не повезло.
Теперь правда, что Java поймал бы эту ошибку во время компиляции, а Python - нет. Это можно рассматривать как недостаток. Аргумент счетчика про-динамической типизации говорит о том, что любой существенный объем кода, который вы пишете, всегда будет содержать ошибки, которые компилятор no может поймать (и, честно говоря, Java даже не является особенно хорошим примером компилятор с сильными статическими проверками, чтобы поймать много ошибок). Так что вам нужно проверить свой код, чтобы найти эти ошибки. И если вы тестируете эти ошибки, вы легко найдете ошибки, в которых вы передали Person
функции, которая нуждается в Duck
. Учитывая это, говорит динамический машинист, язык, который соблазняет вас на , а не тестирование, потому что он находит некоторые ваших тривиальных ошибок, на самом деле плохо . И вдобавок ко всему, он мешает вам делать действительно полезные вещи, такие как повторное использование функции in_the_forest
в Person
.
Лично я разрываюсь в двух направлениях. Мне действительно нравится Python с его гибкой динамической типизацией. И мне действительно нравятся Haskell и Mercury за их мощные системы статического типа. Я не большой поклонник Java или C ++; по моему мнению, у них есть все плохие биты статической типизации с несколькими хорошими битами.