В Python динамическая типизация и утиная типизация — это две концепции, обеспечивающие гибкость при работе с типами данных и объектами. Давайте разберем каждую концепцию отдельно и посмотрим, как они работают вместе.

Динамическая типизация

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

Например, вы можете создать переменную x и присвоить ей целочисленное значение, а позже переназначить ее строковому значению:

x = 5  # x is an integer
x = "Hello, world!"  # x is now a string

Это отличается от языков со статической типизацией, где переменные имеют фиксированные типы, которые устанавливаются во время объявления и не могут изменяться во время выполнения программы.

Утиный ввод

Утиная типизация — это концепция программирования, в которой тип объекта менее важен, чем имеющиеся у него методы и свойства. Он основан на поговорке: «Если что-то выглядит как утка, плавает как утка и крякает как утка, то, вероятно, это утка».

В Python утиная типизация позволяет использовать объект на основе его поведения (т. е. имеющихся у него методов и свойств), а не его класса или типа. Это возможно, потому что Python имеет динамическую типизацию, а это означает, что интерпретатор проверяет совместимость объекта с данной операцией во время выполнения.

Например, предположим, что у вас есть функция, которая вычисляет длину последовательности:

def get_length(sequence):
    return len(sequence)

Функция get_length не заботится о типе входного объекта, если она имеет корректную реализацию метода __len__(), который может быть вызван встроенной функцией len(). Это означает, что вы можете передавать в функцию различные типы объектов, такие как строки, списки или словари, и она будет работать так, как ожидалось:

def get_length(sequence):
    return len(sequence)

string_length = get_length("Hello, world!")
list_length = get_length([1, 2, 3, 4, 5])
dictionary_length = get_length({"a": 1, "b": 2, "c": 3})

Эта гибкость, обеспечиваемая утиной типизацией, является одной из причин популярности Python и удобства работы с ним. Это позволяет вам писать код более общего назначения, не слишком заботясь о конкретных типах используемых объектов.

Подводя итог, динамическая типизация Python позволяет переменным изменять свои типы во время выполнения программы, а интерпретатор определяет типы переменных во время выполнения. Утиная типизация, с другой стороны, делает акцент на поведении объекта, а не на его классе или типе, что позволяет использовать объекты на основе их методов и свойств. Вместе эти концепции обеспечивают гибкость и простоту использования в Python, позволяя создавать код более общего назначения без строгих ограничений по типам.