Типизация в Python и не надо хейтить за динамическую (или надо)


24.02.2020 — Про Python


Чтобы разобраться чё там у Python'a, надо понять что есть вообще, чем отличается и т.д. и т.п.

Тип - множество значений и операций над этими значениями (пасиба вики).

Как знает большинство, бывает статическая и динамическай типизация. А чё-нить ещё знает большинство или только зная это уже хейтит?

Статическая/динамическая, сильная/слабая, явная/неявная.

Максимально быстро по каждому, а то прошлый пост большим вышел.

  1. Статическая - типы устанавливаются на этапе компиляции, динамическая - в рантайме.
  2. Сильная - отсутствие автоматических кастов в другой тип (неявных преборазований). Слабая - наличие таковых.
  3. Явная - указываем типы везде ручками. Неявная - компилятор/интерпретатор занимается этим сам.

Теперь мы знаем что есть и давайте сравним JavaScript и Python.

  • JavaScript - динамическая слабая неявная.
  • Python - динамическая сильная неявная.

Вот как раз в сильной типизации вся сила, как бы это не звучало. Python старается предупреждать о всякой диче, что может произойти, например, по ошибке программиста. Он не даст вам сложить str с int, а вот JavaScript сделает всё возможное, чтобы ваше желание было исполнено.

Давайте глянем на плюсы и минусы между типизацией Python'a и полной противоположностью - статической слабой явной (не знаю есть ли ЯП с такой).

Плюсы:

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

Минусы:

  • теряем скорость;
  • теряем подсказки IDE и подсказки по поводу ошибок (привет Python аннотации которые это фиксят);
  • местами теряем краткость записи из-за необходимости кастовать руками;
  • теряем сигнатуры методов, посмотрев на которые можно понять что передавать (аннотации вновь спасают).

По поводу неявных преобразований в Python'e, то можно смело сказать, что они есть. Дело в том, что тут нет одной стороны. Типо кастим хоть куда, только бы сложить (JS), или не кастим вообще и всегда кидаем исключение. Python старается быть умным. Если есть два типа и операция сложения между ними вполне логична, ясна и понятна - давай сделаем это.

Примером может быть int + float: 1 + 1.1 = 2.1

А пример исключения: "daa" + 1JS выполнится, будет строка "daa1")

Что мне дико не нравится, так это потеря данных при неявных кастах. Но всё нужно уметь варить (в JS я пока просто использую === и !== на всякий)! Тут же и про то, что лучше начинать изучать прогу не с динамического языка (ибо не будет понимания). Всё относительно. Сам я начал свой путь с пасика в 5 классе, спустя несколько лет ушёл на динамическую типизацию слабую и даже не догадывался про тройное равно. Сейчас не ощущаю каких-либо проблем в понимании.

В прошлом посте я рассказал про то, что одна из причин медленности Python'a - отсутствие JIT'a. А вторая - динамическая типизация, НО, не конкретно она сама, а то, как архитектура языка усложняет оптимизацию! И всё по старой причине - Python пытается быть всем и вся. Он дико гибок, за счёт этого оптимайзить сложно, а проверка типов осуществляется при каждом доступе к переменной!

Говоря про реализации Python'a я упомянул Cython, но не сказал что это. А всё очень просто. Это Python с статической типизацией.

Недавние посты


© marshal.by 2020

Исходный код

Сайт работает на Gatsby + prismic и опубликован на GitHub.