0,0
рейтинг
26 февраля 2015 в 08:23

Разработка → Форматирование Python-кода

Введение


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

О читаемости и пойдет речь, а точнее как ее увеличить.

Проблемы форматирования


Идеального форматирования кода не существует. Для каждого языка стоит подстраиваться под общепринятые правила оформления кода. Да что говорить, если среди новичков С++ еще до сих пор войны по поводу ставить скобки на следующей строке или нет.
Для python'а основными проблемами форматирования является «C стиль». Не редко в рассматриваемый язык приходят из С-подобных языков, а для них свойственно писать с символами ")(;".
Символы не единственная проблема, есть еще и проблема избыточности написания конструкций. Питон, в отличие от Java, менее многословен и чтобы к этому привыкнуть у новичков уходит большое количество времени.
Это две основные проблемы, которые встречаются чаще всего.

Стандарты и рекомендации к оформлению


Если для повышения скорости исполнения кода можно использовать разные подходы, хотя эти подходы очень индивидуальны, то для форматирования текста существует прям slyle guide — это pep8. Далее его буду называть «стандарт».
Почитать про стандарт можно здесь, на русском языке можно здесь
Pep8 весьма обширный и позволяет программисту писать РЕАЛЬНО читаемый код.

Он включает:
  • максимальную длину строк кода и документации
  • кодировки файлов с исходным кодом
  • рекомендации как правильно оформлять комментарии
  • соглашения именования функций/классов, аргументов
  • и многое другое

В целом, покрывает множество правил форматирования кода. Однако, стоит заметить, что не все python-программисты соблюдают данные правила.
Большие компании, такие как Google, имеют свои рекомендации к написанию python-кода, их можно почитать здесь и здесь.
Весьма интересное чтиво, рекомендую.

Автоматизируем форматирование


Если посмотреть сколько всяких правил в pep8, то можно сесть за рефакторинг надолго. Вот только это лениво, да и при написании нового кода сиравно будут какие-то ошибки правил. Для этого рассмотрим как же себе можно упростить жизнь.

pep8


Дабы иметь представление сколько ошибок оформления в коде, стоит использовать утилиту pep8.
У нее достаточный список параметров, который позволяет рекурсивно просмотреть все файлы в папках на предмет соответствия стандарту pep8.
Вывод утилиты примерно такой:

$ pep8 --first optparse.py
optparse.py:69:11: E401 multiple imports on one line
optparse.py:77:1: E302 expected 2 blank lines, found 1
optparse.py:88:5: E301 expected 1 blank line, found 0
optparse.py:222:34: W602 deprecated form of raising exception
optparse.py:347:31: E211 whitespace before '('
optparse.py:357:17: E201 whitespace after '{'
optparse.py:472:29: E221 multiple spaces before operator
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'

По нему можно однозначно понять: где ошибка и что случилось.

autopep8


Ошибки стандарта часто повторяются от файла в файлу. И возникает сильное желание исправление автоматизировать. В этом случае на арену выходит autopep8.
Как и pep8, он умеет самостоятельно определять ошибки, а также исправлять их. Список исправляемых ошибок форматирования можно найти здесь
Само использование autopep8 крайне простое и может выглядеть так:

$ autopep8 ./ --recursive --in-place -a

После выполнения данной команды, утилита рекурсивно пойдет по подпапкам и начнет в самих же файлах исправлять ошибки.

autoflake


Можно пойти дальше и в качестве оружия взять autoflake. Эта утилита помогает удалить не используемые импорты и переменные.
Используется примерно так:

$ autoflake --in-place --remove-all-unused-imports --remove-unused-variables -r ./

Тем самым будут рекурсивно почищены файлы в директории.

unify


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

$ unify --in-place -r ./src/

Как и везде, утилита выполнит свое грязное дело рекурсивно для файлов в папке.

docformatter


Все время говорим о самом коде, а о комментариях еще ни разу не шло речи. Настало время — docformatter. Эта утилита помогает привести ваши docstring по соглашению PEP 257. Соглашение предписывает как следует оформлять документацию.
Использование утилиты ничуть не сложнее предыдущих:

$ docformatter --in-place example.py


А все вместе можно?


Выше описаны утилиты, их запуск можно добавить какой-нибудь bash скрипт под магическим названием clean.bash и запускать. А можно пойти и по другому пути и использовать wrapper над этими утилитами — pyformat

Выводы


Python-код легко читается, однако, есть способы сделать лапшу и из читаемого кода.
В данной статье были озвучены некоторые проблемы оформления кода, а также способы поиска этих проблем. Были рассмотрены несколько утилит, которые позволяют в автоматическом режиме убрать некоторые изъяны оформления кода.
Стоит озвучить вслух следующую рекомендацию при написании кода, которая универсальна для любого языка: более важным правилом оформлением, чем подобные pep8-документы — это постоянство стиля. Выбрали в каком стиле будете писать программу, в этом же и пишите весь код.

Если читателям будет интересно, то в следующей статье я опишу как в автоматическом режиме искать ошибки в коде.
Александр Сапронов @WarmongeR
карма
12,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (33)

  • –14
    Очень много субъективных предположений, выданных за объективные, например начало и конец:

    Python, точнее его самый известный представитель CPython

    вы провели или привели исследования, чтобы выяснить какая реализация языка Python является самой популярной?

    Стоит озвучить вслух следующую рекомендацию при написании кода, которая универсальна для любого языка: более важным правилом оформлением, чем подобные pep8-документы — это постоянство стиля. Выбрали в каком стиле будете писать программу, в этом же и пишите весь код.

    Вы ошибаетесь. Не приходилось разбирать чужой код, написанный в соответствии с этой «рекомендацией»?
    • +9
      вы провели или привели исследования, чтобы выяснить какая реализация языка Python является самой популярной?


      Достаточно сказать, что в большинстве Linux'ов стоит именно CPython. А к использованию других реализаций питонов прибегают не так часто и в реальных проектах это скорее исключение, чем правило.

      Вы ошибаетесь. Не приходилось разбирать чужой код, написанный в соответствии с этой «рекомендацией»?


      Да, получалось вполне успешно читать такие проекты. Если проект больше 10к строк кода, то уже не важно существование pep8 или каких-то других стандартов для языка(если смотрим на на другие языки программирования), то никто не будет переписывать весь продакшн код для удовлетворения каких-то там стандартов. Иначе говоря «работает — не трогай».

      • –12
        Достаточно сказать, что в большинстве Linux'ов стоит именно CPython


        Это понятно. Я к тому, что если бы вы указали, что CPython — это эталонная реализация языка, то вопроса о причинах популярности не было.
  • –4
    Спасибо за статью, жду следующую.
  • +1
    Подскажите пожалуйста, какой IDE пользуетесь и как GUI разрабатываете?
    • 0
      PyCharm хорош весьма. Какое именно гуи?
      • –1
        GUI — любое. Desktop GUI или Web.

        В кокой-то момент понял что без интерфейса пользователя плохо, а как его быстро и наглядно делать не нашел информации. Разве что Tkinter можно эффективно использовать, поскольку он в комплектность питона входит.
        • 0
          Desktop GUI и Web это разные совсем тематики.

          Вообще, что для первого, что для второго, стоит ответить на вопросы:

          • Нужен ли GUI?
          • На самом ли деле нужен ли GUI?
          • Для кого делаем GUI?
          • Web или Desktop?
          • Есть системные ограничения?
          • … и вот в таком стиле вопросы все


          От этого и станет ясно какие технологии стоит использовать. Может так сложиться, что программой пользуются по принципу «Запустил один раз и весит в фоне — обрабатывает данные», тогда консольного хватит за глаза
          • 0
            Меня не интересуют подробности технологий, описание разницы реализаций, тонкости построения хорошего интерфейса. Я спрашиваю
            как GUI разрабатываете?


            Вот вы GUI разрабатываете на Python для своих проектов??? Если да — опишите как (насколько полно это описывать — решайте сами). Мне будет достаточно ответа в духе «Tkinter» или «PyQt». Если вы ещё добавите описание вида «без дизайнера форм» — будет совсем хорошо.
          • 0
            Ой, прошу прощения. Не понял что комментарий чуть ниже как раз Вам и принадлежит.
    • 0
      В качестве основной IDE для Python использую Pycharm — это для развесистых проектов, для экспериментов (2-3 py-файла) Sublime Text или vim хватает.
      GUI почти не разрабатываю, однако, если требуется desktop GUI, то беру PyQt. Потому что, давно писал на Qt/C++ и привычка осталась. Сам интерфейс на 90% руками в коде, на 10% (каркас) делаю с QtDesigner, который потом конвертирую в py файл, а затем редактирую под реальные свои нужны.
    • 0
      Для винды есть IronPython, но без дизайнера форм.
      • 0
        IronPython не понравился. Не позволяет использовать готовые Python-библиотеки, например matplotlib.
    • –2
      IDE – vim (как и для всего остального, впрочем). GUI – Qt. Без дизайнера форм отлично всё описывается в инициализаторах классов.
  • +1
    Python, точнее его самый известный представитель CPython, не очень предназначен для каких-либо быстрых расчетов.

    Если решать задачи в лоб (с вложенными или просто огромными циклами, например), получается действительно довольно медленно. Если же пользоваться итераторами, корутинами, стандартными библиотеками itertools, functools или внешней scipy, выходит вполне приемлемая производительность, которой для большинства случаев хватает. Не зря же довольно много ученых выбирают python для своих исследований.

    Плюс ко всему в CPython отлично реализована поддержка больших чисел (тип long), работает просто молниеносно.
    • +1
      numpy (лежит в основе scipy) работает более-менее быстро потому, что там довольно много кода реально на фортране…
      • –1
        Откуда вы про фортран то взяли? C — 53.7%, Python — 45.4%, Others — 0.9%. Цифры из главного репозитория на github.
        • 0
          gfortran он просто так для сборки тащит?
          • 0
            To build any extension modules for Python, you’ll need a C compiler. Various NumPy modules use FORTRAN 77 libraries, so you’ll also need a FORTRAN 77 compiler installed.
            docs.scipy.org/doc/numpy/user/install.html
            • 0
              C таким же успехом можно о любой программе сказать, что в ней много кода на C — почти всё слинковано с glibc.
              • 0
                Когда критичный по скорости исполнения код написан на C или Fortran, как в случае матричных вычислений в numpy, вполне корректно говорить, что скорость работы определяется в том числе наличием этого нативного кода.
                Некоторые, конечно, собирают его без blas/atlas, но это какая-то перверсия, когда вычисления занимают хотя бы десятки минут.

                Если внимательно прочитать мой оригинальный комментарий, то можно узреть, что я лишь утверждал, что нормальная скорость работы numpy определяется тем, что критичные операции реализованы в нативном коде на фортране. В этом нет ничего плохого.
                • 0
                  Да. Но это библиотеки, никак не относящиеся к NumPy. Это отдельные проекты, которые используются в куче другого научного софта. И говорить, что в NumPy «довольно много кода реально на фортране» не корректно. Это лишь использование сторонних нативных библиотек.
                  • +1
                    Угу, недаром numpy core использует функции из cblas… Так что эти «никак не относящиеся» библиотеки реализуют ядро функционала numpy.

                    Я ваш тезис понял и согласен, что форма высказывания была неаккуратная.

                    Имелось ввиду то, что скорость работы scipy/numpy определяется тем, что numpy использует нативную реализацию критичных вычислений.
                    Если посмотреть выше, то я отвечал на следующее утверждение:
                    Если же пользоваться… scipy, выходит вполне приемлемая производительность, которой для большинства случаев хватает. Не зря же довольно много ученых выбирают python для своих исследований.
      • 0
        Ну так и сам CPython не на python написан:)
  • 0
    О, спасибо. А то меня совсем достало постоянно потом ходить по файлу и исправлять пробелы после запятых и прочую ерунду.
  • 0
    Для Sublime есть плагин Python PEP8 Autoformat
    Нажимем ctrl+shift+r и код форматируется.

    А еще есть pytest-pep8
    • 0
      Для Sublime еще есть AutoPEP8: умеет форматировать файлы в директории, а также показывать превью форматирования.
    • 0
      Для Sublime есть github.com/DamnWidget/anaconda На мой взгляд лучший плагин, но только для Sublime 3, но она пока dev и бесплатна также, и ключи со второй подходят.
  • 0
    А однажды прочитать PEP8 и впредь стараться соответствовать ему, что мешает? Тот же Pycharm всегда подскажет, если вдруг допустили ошибку случайно (иногда я нарушаю PEP8 специально, да, и не IDE меня судить).

    Я готов понять использование утилит для автоматического причесывания кода в случаях, когда под руку попался затронутый в комментариях проект на 10 килострок кода, и глаза б ваши не видели этот ад.

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

    Но если вы сами пишете код на пайтоне, почему бы сразу не форматировать нормально? Используя средства автоматического форматирования вы усложняете себе задачу последующего чтения своего же кода. Это не тот код, который вы писали.
    • +2
      А зачем задумываться о том, о чем может думать машина? Читать автоформатирование не мешает — это надо совсем треш писать, чтобы все поменялось до степени нечитания. А вот помарки и прочее исправляются автоформатером
    • +2
      Использование утилит автоматического форматирования не отменяет написание кода по pep8. Большинство рекомендаций, там описанных, легко соблюдать. Но есть не простые места, на первый взгляд, говорю об отступах. Если вы пишете код в фукциональном стиле, то у вас получается длинная строка, в котором «в кучу кони, люди», (словари, генераторы, листы и тд), а потом начинаете думать, где же ставить здесь переносы, чтобы строка занимала не более 79 символов.

      Давно уже заметил, что различные рекомендации по оформлению кода на разных языках программирования, это не скорее не рекомендации, а опыт выработанный кровью. И если 80-90% кода человек может оформить за 20% времени, то остальные моменты пусть доделывает автоматика.

      Для справки, у PyCharm по умолчанию весьма глупая проверка на нарушение правил — подсвечивает не все.
  • 0
    Кстати, если кто пользуется вимом могу посоветовать отличное расширение github.com/hynek/vim-python-pep8-indent
  • 0
    В статье забыли указать про полезный github.com/timothycrosley/isort
    isort your python imports for you so you don't have to.

    isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections. It provides a command line utility, Python library and plugins for various editors to quickly sort all your imports. It currently cleanly supports Python 2.6 — 3.4 using pies (https://github.com/timothycrosley/pies) to achieve this without ugly hacks and/or py2to3.

    И кстати кто-нибудь подключал в pycharm внешний автоформаттер типа pyformat, autoflake, autopep8? Я знаю там встроен свой автоформаттер, но я не нашел как его настроить, добавить исключения. Как подключить isort я совсем не разобрался, неужели там нет возможности цеплять хуки на событие post save для файла?

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