Рубрики
Без рубрики

👨‍💻🤖 3 лучших автоматических форматеров для Python

Первоначально опубликовано в моем блоге: https://www.kevinpeters.net/auto-formatters-for-python, как вы можете … Tagged с помощью Python, производительности, Codequality.

Первоначально опубликовано в моем блоге: https://www.kevinpeters.net/auto-formatters-for-python

Как вы можете видеть в недавнем Опрос разработчиков Stack Overflow , Python – один из самых популярных языков программирования. С недавним ростом хороших автоматических форматов для кода, такого как GOFMT для Голанга или красиво Для JavaScript есть хороший вопрос: какое автоматическое форматер использовать с кодом Python? Автомобиль – это инструмент, который будет отформатировать ваш код таким образом, чтобы он соответствовал инструменту или любым другим стандартам.

Прежде всего, мы должны убедиться, что мы знаем причину, по которой существуют инструменты автоматического форматирования. Prottier – это автоматическое форматер для кода JavaScript. Он используется многими крупными компаниями, такими как Facebook , PayPal, Algolia, Yelp, Discord и многие другие, которые вы можете найти Здесь Анкет Причины этого:

  • Вам не нужно руководство по стилю для проблем с низким уровнем, так как автоматическое форматер решает эти проблемы

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

  • Это также поможет с встроенными разработчиками на кодовой базе, потому что стиль кода согласован

  • Меньше конфликтов слияния, так как стиль почти всегда будет то же

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

Для Python есть три решения:

Autopep8 – GitHub

Autopep8-это автоматическое форматер, построенный, открытый и изготовленный несколькими разработчиками Анкет Возможно, это самое наиболее используемое сейчас, так как это один из старейших инструментов. Он использует Pycodestyle Чтобы проанализировать, какие части вашего кода не подходят для PEP-Guidelines и попытаются их исправить. Существует список функций, перечисленных в чтении репозитория, в котором поддерживаются руководящие принципы PEP. Вы можете найти этот список Здесь Анкет Инструмент также сделает небольшие дополнительные проверки. На момент написания записи в репозитории было около 2200 звезд (июнь 2018 года).

Япф – GitHub

Еще один форматер Python это еще один инструмент, который производится и поддерживается ничем иным, как Google . Он имеет ~ 7200 звезд (июнь 2018 года) на GitHub и следует за другим мышлением по сравнению с Autopep8. Он не будет соответствовать коду, соответствующим руководящим принципам PEP, и не пытается исправить проблемы с личинкой. Это просто отформатирует код. Это требует ручной работы, чтобы сделать код красивым, что тратит время разработчика. Кроме того, YAPF действительно настраивается. Он включает в себя по умолчанию для PEP8, Google, Facebook и стиля хрома. Вы также можете изменить много правил стиля. Более подробную информацию можно найти в Секция ручек Чита. Инструмент также предлагает онлайн -версию, где вы можете попробовать форматирование. Это можно найти Здесь Анкет

Черный – GitHub

Последний популярный автоматический форматер, который рассматривается в этой статье в блоге. Это инициатива Lłukasz Langa Кто является разработчиком Python Core. Инструмент используется различными библиотеками с открытым исходным кодом, такими как Ткань 2 и pytest Анкет У него около 3800 звезд на GitHub (июнь 2018 года), и основной стимул – не иметь такого большого количества вариантов, поэтому вам даже не нужно обсуждать варианты. За этим мышлением также следует Atttier, большой автоматический форматер JavaScript.

Все эти инструменты можно найти на Pypi и быть установленным через PIP или аналогичные менеджеры пакетов Python и могут использоваться в командной строке, что делает их удобными для перекрестного окружающей среды. Вы также должны рассмотреть такой инструмент, как Pre-Commit или Хаски и ворсница Для автоматического предварительного крючка, который работает в каждой среде и который легко установить. С помощью этого предварительного крючка неформатированный код никогда не будет перемещен от машины разработки в удаленный репозиторий. Для сравнения YAPF я буду использовать настройку Facebook, Google и PEP8, поскольку настройка хрома не получает такого большого использования (2 -й пространство – это причина для этого).

Во всех примерах я запускаю конфигурацию по умолчанию для каждого инструмента. Для YAPF это невозможно так просто, поскольку существуют различные базовые конфигурации, которые я хотел попробовать. Это PEP8, Google и Facebook.

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

class Basket():
    reference = models.CharField(
        _('Project reference'), max_length=100, null=True)
class Basket():
    reference = models.CharField(
        _("Project reference"), max_length=100, null=True
    )
class Basket():
    reference = models.CharField(
        _('Project reference'), max_length=100, null=True
    )

На вершине базовый код, yapf (Google, PEP8) не внесли никаких изменений, код в середине отформатируется черным, а нижний форматируется YAPF (Facebook)

Вы можете видеть, что yapf (Facebook) и Black пытаются преобразовать код в многострочные кронштейны, в то время как остальные не делают этого. Разница между Black и YAPF (Facebook) состоит в том, что строки также форматируются в черном, который вы увидите позже. Black использует двойные кавычки для каждой строки, за исключением строк, где включены двойные кавычки.

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

class Basket():
    PRICING_STATUS_CHOICES = (
        (NO_REQUEST,
         _("No Request - there was no manual pricing requested yet")),
        (WAITING_FOR_MANUAL_PRICING,
         _(("Waiting For Pricing - the basket needs someone to"
            "set a manual price for one or multiple lines"))),
        (MANUALLY_PRICED,
         _("Manually Priced - the basket has been priced manually")),
    )

Базовый код, Autopep8 и YAPF (Google, PEP8)

Вы можете видеть, что это был вход для автоматических форматеров, но Autopep8, YAPF (Google) и YAPF (PEP8) ничего не изменили в коде.

class Basket:
    PRICING_STATUS_CHOICES = (
        (
            NO_REQUEST,
            _("No Request - there was no manual pricing requested yet"),
        ),
        (
            WAITING_FOR_MANUAL_PRICING,
            _(
                (
                    "Waiting For Pricing - the basket needs someone to"
                    "set a manual price for one or multiple lines"
                )
            ),
        ),
        (
            MANUALLY_PRICED,
            _("Manually Priced - the basket has been priced manually"),
        ),
    )

черный и япф (Facebook)

Black и YAPF (Facebook) дали тот же результат в конце, так как ввод уже отформатирован с двойными кавычками. Кроме того, оба форматта немного разделили линии.

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

На этот раз мы получаем в основном разные результаты. Если вы пытаетесь определить авто форматера, посмотрите на следующие два примера. Они покажут вам реальные различия между инструментами.

def function_with_really_long_name(normal_variable, another_normal_variable, configuration=None, test_number=1, test_text='dwadawa', test_tuple=('Lorem Ipsum', 21)):
    return None

Базовый код

def function_with_really_long_name(
    normal_variable,
    another_normal_variable,
    configuration=None,
    test_number=1,
    test_text='dwadawa',
    test_tuple=(
        'Lorem Ipsum',
        21)):
    return None

Autopep8

Autopep8 форматирует параметры ниже друг друга, а также запускает новую линию, поскольку он проанализировал, что есть слишком много параметров, чтобы соответствовать. Со значением по умолчанию для test_tuple у него есть некоторые проблемы. Код полностью PEP8-совместимый, но определение кортежа выглядит довольно странно. Мы также можем снова увидеть, что закрывающие кронштейны не перемещаются на новую линию, но вместо этого он выполнит минимальную работу, чтобы сделать код PEP8-совместимой.

def function_with_really_long_name(
    normal_variable,
    another_normal_variable,
    configuration=None,
    test_number=1,
    test_text="dwadawa",
    test_tuple=("Lorem Ipsum", 21),
):
    return None

чернить

Black форматирует код, аналогичный Autopep8, но перемещает заключительные кронштейны на новую линию, а также не форматирует кортеж ненужным образом.

def function_with_really_long_name(
    normal_variable,
    another_normal_variable,
    configuration=None,
    test_number=1,
    test_text='dwadawa',
    test_tuple=('Lorem Ipsum', 21),
):
    return None

yapf (Facebook)

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

def function_with_really_long_name(normal_variable,
                                   another_normal_variable,
                                   configuration=None,
                                   test_number=1,
                                   test_text='dwadawa',
                                   test_tuple=('Lorem Ipsum', 21)):
    return None

yapf (Google), yapf (PEP8)

YAPF с настройкой Google и PEP8 поместит параметры под друг другу, но попытается поставить первый параметр в ту же строку, где начинается функция.

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

def generator_expression():
    Fruit = collections.namedtuple('Fruit', ('name', 'size', 'price', 'super_long_property_in_tuple'))
    fruits = [
      Fruit(name='apple', size=5, price=10.50, super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.'),
      Fruit(name='banana', size=7, price=10.50, super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.'),
      Fruit(name='orange', size=6, price=10.50, super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.'),
      Fruit(name='kiwi', size=1, price=10.50, super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.')]
    complicated_fruits_filtered = [fruit for fruit in fruits if fruit.price >= 10 and size <= 5]

Базовый код

def generator_expression():
    Fruit = collections.namedtuple(
        'Fruit', ('name', 'size', 'price',
                  'super_long_property_in_tuple')
    )
    fruits = [
        Fruit(
            name='apple',
            size=5,
            price=10.50,
            super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.'),
        Fruit(
            name='banana',
            size=7,
            price=10.50,
            super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.'),
        Fruit(
            name='orange',
            size=6,
            price=10.50,
            super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.'),
        Fruit(
            name='kiwi',
            size=1,
            price=10.50,
            super_long_property_in_tuple='super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.')]
    complicated_fruits_filtered = [
        fruit for fruit in fruits if fruit.price >= 10 and size <= 5]

Autopep8

Autopep8 также пытается сделать минимальную работу. NameTuple будет разделен на несколько строк. Аргументы для имен также разделены на две строки. Кроме того, он также попытается оставить текст в той же строке в определении Super_long_property_in_tuple. Выражение генератора просто помещается на следующую строку.

def generator_expression():
    Fruit = collections.namedtuple(
        "Fruit", ("name", "size", "price", "super_long_property_in_tuple")
    )
    fruits = [
        Fruit(
            name="apple",
            size=5,
            price=10.50,
            super_long_property_in_tuple="super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.",
        ),
        Fruit(
            name="banana",
            size=7,
            price=10.50,
            super_long_property_in_tuple="super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.",
        ),
        Fruit(
            name="orange",
            size=6,
            price=10.50,
            super_long_property_in_tuple="super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.",
        ),
        Fruit(
            name="kiwi",
            size=1,
            price=10.50,
            super_long_property_in_tuple="super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.",
        ),
    ]
    complicated_fruits_filtered = [
        fruit for fruit in fruits if fruit.price >= 10 and size <= 5
    ]

чернить

Черный форматирует строки в двойные цитаты. Названная турнир разделен на три строки, где вторая строка – это просто важные данные. Расщепление массива происходит как обычно, и скобки много перемещаются и не ставят за последние элементы. Что действительно интересно, так это то, что строка в строке 10, например, не перемещается в следующую строку.

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

def generator_expression():
    Fruit = collections.namedtuple(
        'Fruit', ('name', 'size', 'price', 'super_long_property_in_tuple')
    )
    fruits = [
        Fruit(
            name='apple',
            size=5,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
        Fruit(
            name='banana',
            size=7,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
        Fruit(
            name='orange',
            size=6,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
        Fruit(
            name='kiwi',
            size=1,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
    ]
    complicated_fruits_filtered = [
        fruit for fruit in fruits if fruit.price >= 10 and size <= 5
    ]

yapf (Facebook)

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

def generator_expression():
    Fruit = collections.namedtuple('Fruit',
                                   ('name', 'size', 'price',
                                    'super_long_property_in_tuple'))
    fruits = [
        Fruit(
            name='apple',
            size=5,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
        Fruit(
            name='banana',
            size=7,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
        Fruit(
            name='orange',
            size=6,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        ),
        Fruit(
            name='kiwi',
            size=1,
            price=10.50,
            super_long_property_in_tuple=
            'super long string here also, lorem ipsum, maybe longer than 80 characters to look for pep8 violations here. lorem ipsum.',
        )
    ]
    complicated_fruits_filtered = [
        fruit for fruit in fruits if fruit.price >= 10 and size <= 5
    ]

yapf (Google), yapf (PEP8)

YAPF с настройкой Google и PEP8 в этом случае будет отформатировать код. Основное различие в настройке Facebook заключается в том, что название именования форматируется по -разному, как мы видели в предыдущих примерах, таких как разделение параметров.

Вывод

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

Черные и Япф имеют свои собственные преимущества и недостатки. YAPF очень настраивается, но я бы порекомендовал сохранить настройки как можно меньше. Для YAPF настройка Facebook очень похожа на Black’s Но я думаю, что это действительно странно, что, например, с кавычками конфигурации по умолчанию не отформатированы по умолчанию. В противном случае, это просто личное предпочтение, в какой конфигурации или какой форматере выбрать.

Лично для меня я выберу Black для будущих проектов, так как он близок к красивее в своем подходе. YAPF может иметь большую поддержку, но я думаю, что это изменится со временем.

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

Оригинал: “https://dev.to/igeligel/the-3-best-auto-formatters-for-python-432p”