Система типов в Python
Содержание
Сегодня я бы хотел поговорить про систему типов в языке Python.
Python — один из самых популярных языков программирования. Его популярность во многом связана с его простотой в использовании и высокой скоростью разработки. Но что значит простота использования? Многие также относят к его преимуществам «лаконичность».
Виды типизации
Типизацию делят на 3 бинарные классификации:
- статическая/динамическая типизация.
- слабая/сильная типизация.
- явная/неявная типизация.
Динамическая типизация
Динамическая типизация — это прием, который позволяет менять тип переменной во время выполнения программы. Иначе говоря, переменная связывается с типом в момент присваивания значения. Это позволяет не определять дополнительные переменные, а менять тип в зависимости от нужных действий, то есть в разных участках кода переменная может принимать значения разных типов.
Python является динамически типизированным языком и позволяет изменять типы переменных во время выполнения программы.
Например:
x = 1
x = "2"
print(x) # 2
Преимущества:
- простота использования, гибкость, удобство, возможность изменять типы переменных во время выполнения программы.
Недостатки:
- возможность ошибок выполнения программы.
- производительность программы ухудшается, так как необходимо выполнять проверку типов во время выполнения программы.
Статическая типизация
Существует другой тип языков, которые являются статически типизированными. Статическая типизация — прием, который позволяет определять тип переменной во время компиляции. Иначе говоря, переменная связывается с типом в момент объявления, и мы не можем изменять тип в зависимости от нужды. Это значит, что мы не можем изменять типы переменных во время выполнения программы. Например, код на C++ вызывает ошибку компиляции, так как мы не можем изменять тип переменной x:
int main() {
int x = 1;
x = "2"; // error: cannot convert from 'const char *' to 'int'
return 0;
}
Преимущества:
- большая скорость выполнения программы
- меньшая вероятность ошибок выполнения программы, так как ошибки исключаются во время компиляции
Недостатки:
- Снижение скорости разработки: Приходится заранее продумать логику структур данных на этапе проектирования системы.
- Время компиляции программы: Компилятору требуется дополнительное время для проверки типов, что может улучшать качество программы, при этом увеличивает время цикла «написал — запустил — проверил».
- Увеличение объема кода: Необходимость постоянно объявлять типы переменных, параметров функций и возвращаемых значений делает код более громоздким по сравнению с динамическими языками. (Хотя возможно это облегчает процесс разработки и чтения кода в будущем.)
Строгость типизации
Еще одна характеристика системы типов — это сильная и слабая типизация (или строгая и нестрогая типизация).
Сильная типизация
Впервые понятие введено в 1974 году Лисков и Зиллесом в работе по CLU, назвавшими сильно типизированными языки, в которых «при передаче объекта из вызывающей функции в вызываемую тип этого объекта должен быть совместим с типом, определённым в вызываемой функции».
Проще говоря, языки с сильной типизацией запрещают смешивание типов (например, числа и строки). В таких языках отсутствует автоматическое преобразование, например при сложении 5 + "10" ответом не будет 510 или 15. Такое действие вызовет ошибку типа.
Python является сильно типизированным языком, это значит, что мы не можем выполнять операции с переменными разных типов.
Например, следующий код вызовет ошибку TypeError:
y = 1
x = "2"
print(x + y) # TypeError: unsupported operand type(s) for +: 'int' and 'str'
Преимущества:
- Надежность: Высокая надежность за счет проверки типов позволяет выявить ошибки во время компиляции программ и статических анализаторов типа
mypy.
Недостатки:
- Гибкость: Меньшая гибкость, требует явного приведения типов, поэтому требует больше объема кода.
Способ задания типов
Ошибочно считать, что все языки с динамической типизацией имеют слабую типизацию. Python является языком с неявной типизацией, это значит, что мы можем не задавать типы переменных во время их объявления. Например, следующий код будет работать без ошибок:
x = 1
print(x)
При этом в языках с явной типизацией типы переменных задаются при объявлении.
Например, на C:
#include <stdio.h>
int main (void) {
char s[] = "Test String";
float x = 0.0;
int y = 0;
printf ("Hello World\n");
return 0;
}
Мы также можем явно задавать типы переменных во время их объявления, для этого в Python предусмотрен специальный синтаксис аннотаций типов.
<variable_name>: <type>
Например:
x: int = 1
print(x)
За что же любят Python?
Python пытается балансировать между типобезопасностью и лаконичностью за счёт скорости написания программ и использования статических анализаторов типов, предназначенных для поиска ошибок несоответствия типов без запуска кода, вроде mypy.
Это отличный подход, который собственно и нравится разработчикам, которые хотели бы писать код, максимально читаемый и понятный. Аннотация типов не влияет на скорость выполнения программы, но при этом помогает находить ошибки в коде до начала выполнения и позволяет разработчикам сделать код более читаемым и понятным. Разработчик сам решает, нужно ли использовать аннотации типов.