В этой статье мы вам расскажем о проверке типов, о различных типах данных в разных языках, а также о неявной типизации и подсказках.
В Python проверка типов выполняется в интерпретаторе. Так как Python — язык с динамической типизацией, он не заставляет пользователя принудительно указывать тип объектов. Это потенциально может привести к ошибкам, причем их будет трудно найти. Чтобы избежать этого, Python можно использовать вместе с другими инструментами и реализовывать проверки типов вместе с собственным алгоритмом неявной типизации.
Существует два метода типизации, за каждым из которых стоят определенные языки программирования:
Проверка типа переменной выполняется во время компиляции. Кроме того, система типов языка заставляет явно объявлять «тип данных» переменной перед ее использованием.
Вот ряд языков программирования со статической типизацией: Scala, Java, C++ и так далее. Например, объявление переменной строкового типа в языке Scala выглядит следующим образом:
var myCar:String = "Mercedes";
В этом примере мы видим, что переменная myCar
объявлена явным образом как тип данных String
со значением Mercedes
.
В этих языках проверка типа переменной выполняется во время выполнения. Кроме того, система типизации языка не требует явного объявления типа данных переменной перед ее использованием. К языкам программирования с динамической типизацией относятся Python, JavaScript, Ruby и так далее.
Например, переменная строкового типа в языке Python определяется следующим образом:
myCar = "Mercedes"
Здесь мы видим, что переменную myCar не нужно явно объявлять.
Тип переменной в Python можно определить при помощи встроенной функции type()
. Функция type()
может использоваться во время выполнения программы в целях отладки, чтобы точно идентифицировать типы используемых переменных. Давайте проверим тип переменной:
my_var = 12 print(type(my_var))
Приведенный выше код выдает в качестве результата ‘int’. Тип данных переменной my_var
является целочисленным, и функция type()
определяет его именно таким образом.
При помощи функции isinstance(' obj ',' class ')
в языке Python можно определить, является ли данный объект ('obj'
) экземпляром класса ('class'
). Возвращается булево значение (True
или False
).
my_var = "Hello" print(isinstance(my_var,str))
Приведенный выше код выдает в качестве результата True
. Поскольку тип данных переменной my_var
строковый, то данная переменная является экземпляром класса str
и функция isinstance()
это удостоверяет.
В Python действует популярный принцип: «Если это выглядит как утка, плавает как утка и крякает как утка, то это, вероятно, и есть утка». Попросту говоря, тип объекта или класса не имеет значения, но объект должен содержать аналогичные методы и свойства, тогда объект может использоваться для определенной цели.
Давайте разберем это на конкретном примере.
У нас есть два класса: Duck
и Human
. Класс Duck
содержит методы quack
и fly
. Аналогично класс Human — это класс со своим собственным набором методов quack
и fly
. Duck
и Human
это разные классы и, соответственно, объекты этих классов также отличаются друг от друга. Однако класс Human
содержит те же методы, quack
и fly
, что есть и в классе Duck
. Ещё у нас есть метод fly_quack()
. Он больше подошел бы утке (класс Duck
), чем человеку (класс Human
), так как с помощью данного метода можно одновременно крякать и летать.
class Duck: def quack(self): print('Quack') def fly(self): print('Flap') class Human: def quack(self): print('Trying to Quack like a duck') def fly(self): print('Spreading my arm to flap like a duck') def fly_quack(thing): thing.quack() thing.fly()
Давайте теперь создадим в переменной du
экземпляр класса Duck
и передадим его в функцию fly_quack(du)
. Точно также в переменной h
создадим экземпляр класса Human
и передадим его в ту же функцию.
du = Duck() fly_quack(du) h = Human() fly_quack(h)
Результат выполнения данного кода будет следующим:
Quack Flap Trying to Quack like a duck Spreading my arm to flap like a duck
Поскольку Duck
и Human
это разные классы, Python повторно вызывает функцию fly_quack()
для экземпляра класса Human
. И хотя класс Human
имеет похожие методы quack
и fly
, типы объектов были разными и поэтому все работает правильно и вызываются верные методы.
У динамически типизированных языков, таких как Python, есть свои мощные преимущества, но есть и некоторые недостатки. Одним из недостатков является возникновение ошибок выполнения (runtime error) когда Python не производит принудительного преобразования типов. В результате могут возникать баги, которые с увеличением длины кода становится все трудней найти.
Подсказки типов реализованы в Python начиная с версии 3.5. А более старые версии могут не поддерживать данный функционал.
Давайте посмотрим простой пример без подсказок типов и модуля mypy.
Данная функция предназначена для вычитания целочисленных значений. Она принимает на вход два целых числа и возвращает их разность.
def sub_this(x,y): return 'Subtraction' print(sub_this(8,'hello'))
Здесь функция должна принимать два целых числа x
и y
, но, поскольку никаких ограничений не наложено, она может принимать переменные любого типа данных. Также надо заметить, что данная функция вернет значение 'Subtraction'
при любых входных данных, а нам бы хотелось видеть целочисленное значение.
Давайте рассмотрим выполнение данного кода с подсказками и модулем mypy
. С его помощью можно реализовать проверку статических типов и легко уменьшить количество ошибок в программе.
mypy — это модуль Python, который помогает в проверке статических типов. Он использует собственную динамическую проверку Python или неявную («утиную») типизацию с подсказкой самого типа.
Для начала вам нужно установить сам модуль mypy:
pip install mypy
Далее вам нужно создать файл с именем mypy_example.py на своем локальном компьютере и сохранить туда следующий код:
def sub_this(x:int,y:int) -> int: return 'Subtracted two integers' print(sub_this(8,4))
Это простая программа, которая принимает два целых числа в качестве входных данных в параметре, а после ‘->’ показывает тип возвращаемых данных, который также является целочисленным (‘int’). Но хотя функция должна возвращать целочисленное значение (int), возвращается строка ‘Subtracted two integers’.
Запустите указанный выше код в терминале следующим образом:
mypy mypy_example.py
После этого будет показана ошибка, указывающая на несоответствие типов (должен быть ‘int», а выдается ‘str’).
Давайте теперь изменим тип возвращаемого значения. Заменим строковое значение на разницу двух целых чисел. Таким образом, будет возвращаться целочисленное значение.
def sub_this(x:int,y:int) -> int: return x - y print(sub_this(8,4))
Мы видим, что программа выполняется успешно, никаких проблем не обнаружено.
Дочитав эту статью до конца, вы познакомились с проверкой типов и узнали о разных системах типизации в разных языках программирования. Также вы познакомились с методами type()
и isinstance()
языка Python и с неявной («утиной») типизации. Еще вы узнали о подсказках типов и модуле mypy
.
Pydantic - это мощная библиотека проверки данных и управления настройками для Python, созданная для повышения…
Python предлагает набор библиотек, удовлетворяющих различные потребности в визуализации, будь то академические исследования, бизнес-аналитика или…
В Python для представления данных в двоичной форме можно использовать байты. Из этой статьи вы…
В этой статье рассказывается о том, что такое Werkzeug и как Flask использует его для…
При работе с датами часто возникает необходимость прибавлять к дате или вычитать из нее различные…
В этом руководстве мы рассмотрим, как добавить социальную аутентификацию с помощью GitHub и Google в…