В этой статье мы вам расскажем о проверке типов, о различных типах данных в разных языках, а также о неявной типизации и подсказках.
В 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.
Если вы ищете работу на Python, на Talanto.work сейчас есть варианты для junior, middle, senior…
Рынок Python-вакансий большой, но удобным его назвать сложно. Формально вакансий много, однако в реальном поиске…
Срезы в Python — это больше, чем a[2:7]. В статье — быстрый разбор полезных приёмов:…
В этой статье мы рассмотрим возведение в степень в Python с помощью различных методов, от…
Дубликаты в списке Python — частая проблема. В статье показано, как быстро убрать повторы, в…
Услуга виртуального хостинга на SpaceWeb позволяет арендовать часть сервера (shared-сервера) и разместить на нём свой…