Python - один из самых популярных языков программирования. Как мы писали, в январе 2022 года он во второй раз за свою историю стал лидером ежемесячного рейтинга языков программирования Tiobe. Рост популярности Python за год составил 1,86%.

Популярность языка обусловлена его относительной простотой - работать с ним может быстро начать даже новичок. Конечно, никто не говорит, что этот новичок сможет сразу же писать высоконагруженные проекты, нет. Но решать задачи базового уровня - вполне. Но все же есть проблемы даже здесь, и о них поговорим в статье. Разбираем подводные камни Python вместе с Алексеем Некрасовым, лидером направления Python в МТС, программным директором направления Python и спикером профессии “Python-разработчик” в Skillbox.

Немного о достоинствах языка

На Хабре очень много статей о достоинствах Python, поэтому повторяться не будем. Скажем только, что язык действительно знаменит своей простотой. Причем с течением времени в нём появилось много “синтаксического сахара”, который позволяет быть ему немногословным и понятным языком, похожим на псевдокод. А всё сложное убрано “под капот”, чтобы не отвлекать разработчика. Простота позволяет быстро создавать прототипы и проверять гипотезы. Благодаря этому новичкам проще всего начать изучать программирование с Python.

Что такое синтаксический сахар? Это набор синтаксических конструкций, применение которых не влияет на поведение программы, но делает использование языка более удобным для человека. Например, паттерн “декоратор”:

def decorator_log(func):
   def wrapper(*args, **kwargs):
       print("вызов функции с параметрами", args, kwargs)
       res = func(*args, **kwargs)
       return res
   return wrapper

def func_1():
   print('Тестовая функция')

func_1 = decorator_log(func_1)

# Вместо func_1 = decorator_log(func_1) можно теперь написать:

@decorator_log
def func_1()
   print('Тестовая функция')

Таких конструкций в языке достаточно много, они упрощают чтение кода и работу с ним. 

Интерпретатор Python берёт на себя всю скучную и сложную работу по управлению памятью, потоками и т.д. Но есть и проблема. Дело в том, что из-за всех этих приятных плюсов Python теряет в скорости по сравнению с другими языками программирования.

Подробно о проблемах

Кроме потерь в скорости есть и другие подводные камни, о которых далеко не всегда знают начинающие разработчики. Среди них особенно выделяются две крупные проблемы, это динамическая типизация и так называемый "новый сахар".

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

Python - динамически типизированный язык программирования. Это позволяет быстро разрабатывать прототипы и писать код. Динамическая типизация, если объяснять “на пальцах”, значит, что одна и та же переменная в разное время может ссылаться на данные разного типа. Например:

data = input() or '123456'  # сейчас в переменной data лежит строка
data = int(data)  # теперь в переменной data лежит целое число

И это будет работать.

Статистические языки программирования, например C, такого сделать не позволяют. Но в динамической типизации есть подвох. Если в простых проектах все ок и проблем не возникает, то, чем масштабнее проект на Python, тем больше появляется ошибок, связанных с типом переменных. Так, где-то далеко в коде введена функция, которая на вход принимает переменную data, введенную пользователем. В функции проверили, что введенное число является двузначным:

if len(data) != 2: print("Нужно ввести двухзначное число")

При выполнении этого кода мы внезапно получаем ошибку

if len(data) != 2: TypeError: object of type 'int' has no len()

Это означает, что в каком-то участке нашего кода строка уже переведена в число, и добавлена в переменную data. Подобные ошибки - далеко не редкость. Чаще всего они возникают на проектах, где работает от двух человек. Для того, чтобы ошибок не было, необходимо писать тесты, которые проверяют, нужный ли формат данных у переменных. У статических языков программирования таких проблем нет.

Еще один вариант решения - использование псевдостатической типизации и ее проверки при помощи статического анализатора mypy. Если проблемы с типами данных не нужны, то потребуется писать код следующим образом:

data: str = input() or '123456'
number: int = int(data)
if len(number) != 2:
print("Нужно ввести двухзначное число")

После написания кода приходится запускать для проверки mypy. Система проверяет, что int как строка нигде не используется. И если запустить mypy, то появится ошибка о передаче неверной переменной в функцию len:

​​error: Argument 1 to "len" has incompatible type "int"; expected "Sized"

Почему здесь употребляется термин "псевдостатическая типизация"? Дело в том, что при запуске скрипта Python проверка не будет проводиться сразу же, так что разработчик не будет знать, корректно ли выполняется передача значения в функцию len или нет. Ошибка появится лишь тогда, когда будет запущена программа с передачей в нее входного значения.

Новый сахар и усложнения в языке

Python постоянно развивается, в каждой новой версии языка появляется что-то новое, что упрощает разработчикам жизнь, позволяя решить задачу кодом с меньшим количеством строк, чем раньше. Но здесь и кроется проблема - программист может увлечься созданием конструкций, которые занимают меньше строк кода, но при этом и значительно уменьшают его читаемость.

Пример - задача по очистке входных данных с приведением их к целым числам. Раньше код программы выглядел бы следующим образом:

from typing import Optional

def to_int(string: str) -> Optional[int]:
   try:
       return int(string)
   except ValueError:
       return None

data = ['sadf', '12', '1', 'a1']
filter_data = []

for i_str in data:
   i_number = to_int(i_str)
   if i_number is not None:
       filter_data.append(i_number)

print(filter_data)

Но начиная с версии 3.8 блок с for вполне можно записать следующим образом:

filter_data = [y for x in data if (y := to_int(x)) is not None]

Опытный разработчик в этом разберется без проблем, но для новичка чтение кода будет сложной задачей.

Какие еще есть сложности?

В целом, их не так мало. Обучение Python можно разделить на несколько этапов, и на каждом из них будут встречаться проблемы. Что касается этапов, то вот они:

  • Изучение простого синтаксиса, типов данных, функций, классов и т.д. На этом этапе нужно научиться понимать простые типы и структуры данных, а также “набить руку” на решении множества простых задач.

  • Изучение паттернов, которые реализованы уже в самом языке: декораторы, итераторы, генераторы, контекст менеджеры и т.д. На этом этапе идет осознание паттернов проектирования и как они реализованы в самом языке. Тут новичку из другой сферы будет непросто, но часто в осознании этих тем помогают наставники или хорошо подобранные статьи.

  • Изучение различных прикладных фреймворков: web (flask, FastApi, Django и др.), работа с БД (SQLAlchemy, sqlite3, Tortoise ORM и др.), работа с данными (numpy, pandas, marshmallow, pydantic и др.) и т.д. Здесь сталкиваемся со сложностью в определении направления своего развития и выстраивания своего маршрута в изучении доп. инструментов. Новичкам я бы посоветовал для этого проконсультироваться с опытным разработчиком или наставником.

  • Углублённое изучение языка: метаклассы, дескрипторы и т.д. В обычной работе разработчик с этим практически не встречается, так как 90% всех задач можно решить без этих знаний. Но если вы хотите стать первоклассным разработчиком, то этих тем вам не обойти.

В целом, обойти проблемы помогает постоянное обучение, а также более опытные коллеги и наставники. Не бойтесь обращаться к ним за помощью, как говориться: “Не тот глуп, кто не знает, но тот, кто знать не хочет.” К слову, если у вас возникли проблемы на каком-то из этих этапов, можете писать мне, постараюсь помочь.

А что насчет перспектив языка?

Если коротко, то с уверенностью могу сказать - они есть, изучать Python стоит, не сомневайтесь.

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

Пять лет назад, чтобы устроиться junior python web-разработчиком нужно было уметь решать алгоритмические задачи и знать основы языка программирования. А сейчас  добавилось следующее:

  • знание одного из фреймворка Flask/Django (желательно ещё и асинхронного фреймворка, например, FastAPI);

  • знание SQL и работа с PostgreSQL;

  • знание тестовых фреймворков pytest, unittest;

  • знание принципов контейнеризации и работы с docker;

  • знание основ Linux.

В ближайшее три-пять лет спрос будет расти на middle и senior разработчиков, так как именно они выполняют основную часть задач в IT-компаниях. Если смотреть на спрос стажёров/junior, то тут всё сложнее по следующим причинам:

  • Junior разработчик приносит только убыток компании, так ему нужен наставник (уровня middle/senior). В итоге на решение определенной задачи с учеником тратится больше времени, чем если бы задачу делал сам наставник.

  • Часто через полгода-год стажер/junior уходит из компании, в которой обучался, в другую с увеличением зарплаты в среднем в 2 раза. Соответственно, терпит убытки компания, которая первой наняла молодого специалиста на работу.

  • Завышенные ожидания у стажёров/junior. Многие переходят из других сфер, где они уже привыкли к своему доходу и не готовы переходить, к примеру, со 100 тыс. руб в месяц на 50 тыс. руб.

Через три-четыре года у стажёров/junior начнёт появляться конкурент в лице ИИ. Недавно компания DeepMind (дочка Alphabet), выполнила на платформе Codeforces 10 тестов и попала в 54% лучших участников. Вполне вероятно, что в скором будущем ИИ сможет решать простые, шаблонные задачи, которые в обычной ситуации дают стажерам/junior-разработчикам.

В качестве вывода

Подводя итог, мы видим, что если вы хотите перейти в сферу IT как python-разработчик, то вам нужно:

  • Максимально сконцентрировать свои силы на обучении, учиться предстоит многому, это будет занимать время.

  • Быть готовым тому, что в течение полугода-года ваша зарплата не превысит 100 тыс. руб. в месяц.

  • Постараться устроиться на первую работу и начать учиться у более опытных коллег.

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