Аналитика
Новый синтаксис старой команды with в Python 3.10

Новый синтаксис старой команды with в Python 3.10

Как же долго моё чувство прекрасного страдало… Но в Python 3.10 появился новый парсер синтаксических конструкций Python!

Больше новшеств Python 3.10.

С новым парсером в Python 3.10 появилась возможность разбора не-LL(1) грамматик, что позволило исправить давнишние проблемы в синтаксисе. В частности, я всегда советовал студентам и коллегам использовать скобки для группировки длинных команд вместо обратной черты \.

Часто код получается более выразительным и менее уродливым (что для меня также важно). Так, например код:

    very_long_operation_result = some_variable[very_important_index] + \
        some_another_variable + and_here_we_call_function(with_wrong_param, \
        and_this_param, one_more_function(once_again_param, its_never_enough) \
        and_param_which_should_not_be_used) + one_more_variable

Можно, на мой взгляд, написать более читаемо:

    very_long_operation_result = (
        some_variable[very_important_index]
        + some_another_variable
        - and_here_we_call_function(
            with_this_param,
            and_this_param,
            one_more_function(once_again_param, its_never_enough)
        )
        + one_more_variable
    )

Можете считать меня перфекционистом (что точно не про меня) и занудой (этого немного есть)… Но я довольно много раз получал весёлые баги от того, что не мог с первого раза прочитать нормально подобную формулу. Или же найти ошибку в знаке - тот минус в 4-ой строке почему-то был плюсом, а функция возвращала ненулевой результат в редких случаях.

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

Новый нормальный контекстный менеджер with

Так вот я к чему… Даже с моими доводами выше, я иной раз получал ответ: "PEP-8 разрешает, да и с конструкцией with так нельзя". Нельзя было, ибо парсер не позволял! А сейчас можно:

    with (CtxManager() as example):
        ...

    with (
        CtxManager1(),
        CtxManager2()
    ):
        ...

    with (
        CtxManager1() as example1,
        CtxManager2() as example2
    ):
        ...

Все эти замечательные скобочки теперь работают и при использовании контекстных менеджеров с with!

В примерах также есть и иные подходы. Я не считаю их также удобными:

    with (CtxManager1() as example,
          CtxManager2()):
        ...

    with (CtxManager1(),
          CtxManager2() as example):
        ...

Поясню. Отступы в Python имеют довольно важное значение. По большей части это "Провалиться на один уровень вложенности/логики вглубь". А различный код типа:

    def function():
        def some_internal_function():
            and_here_we_define_variable = (lets_calc_something
                                            + do_not_stop_please
                                            + if_you_dont_understand
                                            + my_pain)
            some_thing_else()
            ...

Такой код я называю "топором", ибо похоже: вот у нас рукоятка, вот пошла "борода". Помимо чисто геометрического отвращения, отвращения логического ("отступ = логический уровень") я испытываю боль при доработке такого кода: а если нужно ещё добавить вызов функции для прибавления к значению? В diff будет куча строчек, хотя я добавил по факту одну...

В общем, теперь можно писать более единообразно и правильно (на мой взгляд). Кто знает, может по такой радости и вернусь программировать на Python!

Также может быть вам интересно:

Добавляем постраничную пагинацию на Django сайт

На сайтах часто встречаются многостраничные объекты: список товаров, список заметок и т.д. Поэтому важно уметь добавить навигацию по страницам на Django-проекте.

Читать »

Маленькая книга о Go (golang)

Маленькая книга о Go распространяется под лицензией Attribution-NonCommercial-ShareAlike 4.0 International license. Вы не должны платить за эту книгу.

Читать »
Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

Письма об ошибках, отчёты на почту, восстановление паролей - всё это полезно при работе с сайтом. Django предоставляет удобный способ это сделать с минимумом настроек!

Фото Добавляем поддержку медиа-файлов в Django проект

Добавляем поддержку медиа-файлов в Django проект

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

Фото Настройка журналирования (логирования) в Python с примерами

Настройка журналирования (логирования) в Python с примерами

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

Фото Шаблон разработки ПО — Model View Controller (MVC)

Шаблон разработки ПО — Model View Controller (MVC)

MVC - один из самых распространённых архитектурных шаблонов разработки. Часто используется в различных фреймворках. В том числе и в Django.

Фото Пример своей консольной команды в Django проекте

Пример своей консольной команды в Django проекте

Если вы работали с Django проектом, то, скорее всего, запускали команды из консоли (manage.py). В Django есть простой способ писать свои команды для управления проектом.

Фото Разграничение прав доступа на Django сайте

Разграничение прав доступа на Django сайте

Почти на любом веб-сайте необходимо разделять пользователей на группы и предоставлять им разные возможности. В Django есть довольно серьёзная система прав доступа для пользователей - давайте её рассмотрим!

Фото Пользователи и их создание в Django - своя регистрация на сайте

Пользователи и их создание в Django - своя регистрация на сайте

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

Фото Как на Bash посчитать число строк в проекте (директории)

Как на Bash посчитать число строк в проекте (директории)

Ниже будет представлен однострочник, решающий данную задачу на Bash + пошаговое описание его работы.