Инструмент для преобразования кода Python в соответствие с PEP8

113

Я знаю, что есть инструменты, которые проверяют, соответствует ли ваш код Python PEP8, например, есть и онлайн-сервис, и модуль Python .

Однако я не могу найти службу или модуль, который может преобразовать мой файл Python в автономный действительный файл Python PEP8. Кто-нибудь знает, есть ли?
Я предполагаю, что это возможно, поскольку PEP8 - это внешний вид кода, верно?

Чэнь Се
источник
1
Я не думаю, что есть какой-либо инструмент, который преобразует код в код, совместимый с PEP8. PEP8 также включает правила именования переменных, поэтому, если такой инструмент существует, он также переименовывает ваши имена переменных, и тогда вы не сможете понять свой собственный код.
Ашвини Чаудхари
1
@AshwiniChaudhary Это хороший момент, также стоит упомянуть, что изменение имен переменных может повлиять на других, уже использующих ваш код, поэтому это не всегда хорошая идея. (autopep8 этого не делает.)
Энди Хайден

Ответы:

38

К сожалению, у "pep8 storming" (всего проекта) есть несколько отрицательных побочных эффектов:

  • множество конфликтов слияния
  • сломай мерзкую вину
  • затруднить обзор кода

В качестве альтернативы (и благодаря @yp за идею ) я написал небольшой пакет, который autopep8 использует только те строки, над которыми вы работали с момента последнего коммита / ветки:

По сути, выход из проекта немного лучше, чем вы его нашли :

pip install pep8radius

Предположим, вы выполнили свою работу masterи готовы совершить:

# be somewhere in your project directory
# see the diff with pep, see the changes you've made since master
pep8radius master --diff
# make those changes
pep8radius master --diff --in-place

Или очистить новые строки, которые вы сделали после последнего коммита:

pep8radius --diff
pep8radius --diff --in-place

# the lines which changed since a specific commit `git diff 98f51f`
pep8radius 98f51f --diff

В основном pep8radiusэто применение autopep8 к строкам в выводе git / hg diff (из последнего общего коммита ).

Этот скрипт в настоящее время работает с git и hg, если вы используете что-то еще и хотите, чтобы это работало, напишите комментарий / проблему / PR !

Энди Хайден
источник
2
+1 очень хорошая инициатива ... я думаю о том, как сделать плагин Notepad ++ для той же цели ... так как это мой любимый редактор в Windows
kmonsoor
1
@kmonsoor хорошая идея, я не думал о плагинах редактора! Дайте мне знать на github любым способом, которым я могу помочь / упростить использование вне CLI ... Я предвижу несколько (решаемых) проблем.
Энди Хайден
здесь я нашел интересный список плагинов редактора github.com/jcrocholl/pep8/wiki/RelatedTools , хотя не повезло с Notepad ++ ...
kmonsoor
1
Я только что создал скрипт для соединения Notepad ++ и Autopep8 на основе другого плагина «Python Script». Однако это работает. Пожалуйста, проверьте здесь: bit.ly/pep8_tonizer
kmonsoor
185

Вы можете использовать autopep8 ! Пока вы делаете себе чашку кофе, этот инструмент удачно устраняет все те надоедливые нарушения PEP8, которые не меняют смысла. кода.

Установите его через pip:

pip install autopep8

Примените это к конкретному файлу:

autopep8 py_file --in-place

или вашему проекту (рекурсивно), подробный вариант дает вам некоторую обратную связь о том, как это происходит :

autopep8 project_dir --recursive --in-place --pep8-passes 2000 --verbose

Примечание: иногда 100 проходов по умолчанию недостаточно, я устанавливаю его на 2000, поскольку он достаточно высокий и будет перехватывать все, кроме наиболее проблемных файлов (он перестает проходить, как только не находит разрешаемых нарушений pep8) ...

На этом этапе я предлагаю повторно протестировать и выполнить фиксацию!

Если вы хотите «полного» соответствия PEP8: одна из тактик, которую я использовал, - запустить autopep8, как указано выше, затем запустить PEP8, который распечатает оставшиеся нарушения (файл, номер строки и т. Д.):

pep8 project_dir --ignore=E501

и вручную изменить их по отдельности (например, E712s - сравнение с логическим значением).

Примечание: autopep8 предлагает --aggressiveаргумент (чтобы безжалостно "исправить" эти изменяющие смысл нарушения), но будьте осторожны, если вы действительно используете агрессивный режим, вам, возможно, придется отлаживать ... (например, в numpy / pandas, True == np.bool_(True)но не True is np.bool_(True)!)

Вы можете проверить, сколько нарушений каждого типа (до и после):

pep8 --quiet --statistics .

Примечание: я считаю, что E501 (слишком длинная строка) - это особый случай, поскольку их, вероятно, будет много в вашем коде, и иногда они не исправляются с помощью autopep8.

В качестве примера я применил эту технику к базе кода pandas .

Энди Хайден
источник
@hayden Есть ли у вас какие-либо комментарии о том, насколько это надежно, и о соотношении автоматических исправлений и странных проблем, которые он создает?
Мариус
@Marius Я использовал это в коде pandas (который довольно большой), и он не показал никаких странных проблем, он не изменит код, который меняет значение , я обновил свой ответ, чтобы упомянуть об этом. Раньше у него была проблема с хэшбэнгом Sphinx (теперь ошибка в PEP8 исправлена).
Энди Хейден
2
Обеспечивает ли это применение Strunk and White в комментариях?
Эрик
1
С 25 октября 2017 г. pep8упомянутый в этом ответе пакет был переименован в pycodestyle: github.com/PyCQA/pycodestyle/releases/tag/1.7.1
hb20007
8

@Andy Hayden дал хороший обзор autopep8. В дополнение к этому есть еще один пакет под названием pep8ify который также делает то же самое.

Однако оба пакета могут удалять только ошибки lint, но не могут форматировать код.

little = more[3:   5]

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

little = more[3:5]

Иногда это даже разрушает ваше ручное форматирование. Например

BAZ = {
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
}

будет преобразован в

BAZ = {[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]}

Но вы можете сказать ему игнорировать некоторые части.

BAZ = {
   [1, 2, 3, 4],
   [5, 6, 7, 8],
   [9, 10, 11, 12]
}  # yapf: disable

Взято из моего старого сообщения в блоге: Автоматически PEP8 и форматируйте код Python!

ChillarAnand
источник
2
Является ли little = more[3: 5]ошибка в pep8 (библиотеке)? За yapf определенно будущее, алгоритм, лежащий в основе этого (по сути, кратчайший путь в графике всех параметров форматирования), является очень элегантным решением и, вероятно, будет иметь меньше ошибок, а также каноническое форматирование.
Энди Хайден,
@AndyHayden Похоже, это отсутствующая функция, она не исправляет E225
ChillarAnand
5

Если вы используете eclipse + PyDev, вы можете просто активировать autopep8 в настройках PyDev: Windows -> Preferences -> введите autopep8 в фильтр поиска.

Отметьте "использовать autopep8.py для форматирования кода?" -> ОК

Теперь форматирование кода CTRL-SHIFT-F в eclipse должно форматировать ваш код с помощью autopep8 :)

Скриншот

морк
источник
3

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

Потому что переформатирование должно быть более точным - если он переформатировал что-то, что вы не хотите, оно стало бесполезным - они покрывают меньшую часть PEP, линтеры показывают гораздо больше.

Все они имеют разные права на настройку - например, pylinter настраивается по всем своим правилам (можно включать / выключать все типы предупреждений), черный вообще не настраивается.

Вот несколько полезных ссылок и руководств:

Документация:

Линтеры (в порядке популярности):

Средства форматирования кода (в порядке популярности):

Михаил_Сам
источник
1

Много.

IDE обычно имеют встроенные возможности форматирования. IntelliJ Idea / PyCharm делает, то же самое касается плагина Python для Eclipse и так далее.

Существуют средства форматирования / линтеры, которые могут работать с несколькими языками. https://coala.io - хороший тому пример.

Затем есть одноцелевые инструменты, многие из которых упоминаются в других ответах.

Один из конкретных методов автоматического переформатирования - это проанализировать файл в дереве AST (без отбрасывания комментариев), а затем выгрузить его обратно в текст (что означает, что исходное форматирование не сохраняется). Примером этого может быть https://github.com/python/black .

user7610
источник