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

Рефакторинги Python часть 3

Написание чистого, Pythonic Code – это все возможное, чтобы сделать его понятным, но кратким, насколько это возможно. Этот… Теги с Python, Codequality.

Объясняя рефакторинги (2 части серии)

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

В центре внимания этой серии есть, почему эти изменения являются хорошими идеями, а не только о том, как их сделать.

1. Добавить охранник

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

В качестве примера давайте посмотрим на эту функцию:

def should_i_wear_this_hat(self, hat):
    if isinstance(hat, Hat):
        current_fashion = FASHION_API.get_fashion(FASHION_TYPE.HAT)
        weather_outside = self.look_out_of_window()
        is_stylish = self.evaluate_style(hat, current_fashion)
        if weather_outside.is_raining:
            print("Damn.")
            return True
        else:
            print("Great.")
            return is_stylish
    else:
        return False

Это довольно сложно разбирать, учитывая два слоя гнездования. Когда я доберусь до еще Внизу мне нужно щедрость и вперед немного между этим и Если Тест сверху, прежде чем я понял, что происходит. Это Если Состояние – это чек для краевого корпуса, где-то, что не является шляпой. Так как мы просто вернемся Ложь Здесь это идеальное место для введения охранника:

def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    current_fashion = get_fashion()
    weather_outside = self.look_out_of_window()
    is_stylish = self.evaluate_style(hat, current_fashion)
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        return is_stylish

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

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

2. Swap Если/else, чтобы удалить пусто, если тело

Один шаблон мы иногда видим, является условным, где в основном корпусе ничего не происходит, и все действия в еще пункт.

if location == OUTSIDE:
    pass
else:
    take_off_hat()

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

if location != OUTSIDE:
   take_off_hat()
else:
   pass

У нас тогда есть еще пункт, который ничего не делает, поэтому мы можем удалить его.

if location != OUTSIDE:
    take_off_hat()

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

3. Merge добавить в объявление списка

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

hats_i_own = []
hats_i_own.append('panama')
hats_i_own.append('baseball_cap')
hats_i_own.append('bowler')

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

hats_i_own = ['panama', 'baseball_cap', 'bowler']

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

4. Переместить задания ближе к своему использованию

Сфера местных переменных всегда должна быть так же плотно определена как можно более и практически осуществимо.

Это означает, что:

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

Давайте сделаем другой взгляд на предыдущий пример.

def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    current_fashion = get_fashion()
    weather_outside = self.look_out_of_window()
    is_stylish = self.evaluate_style(hat, current_fashion)
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        return is_stylish

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

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

def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    weather_outside = self.look_out_of_window()
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        current_fashion = get_fashion()
        is_stylish = self.evaluate_style(hat, current_fashion)
        return is_stylish

Мы могли бы тогда идти еще один шаг вперед и встроить IS_STYLISH Переменная. Это показывает, насколько небольшие рефакторины часто могут опираться друг на друга и привести к дальнейшим улучшениям.

def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    weather_outside = self.look_out_of_window()
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        current_fashion = get_fashion()
        return self.evaluate_style(hat, current_fashion)

5. Используйте элементы (), чтобы напрямую раскинуть значения словаря

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

hats_by_colour = {'blue': ['panama', 'baseball_cap']}
for hat_colour in hats_by_colour:
    hats = hats_by_colour[hat_colour]
    if hat_colour in self.favourite_colours:
        think_about_wearing(hats)

В это:

hats_by_colour = {'blue': ['panama', 'baseball_cap']}
for hat_colour, hats in hats_by_colour.items():
    if hat_colour in self.favourite_colours:
        think_about_wearing(hats)

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

6. Упростить сравнение последовательности

Что-то, что мы часто делаем, это проверьте, есть ли список или последовательность элементов, прежде чем мы попробуем что-то сделать с ним.

if len(list_of_hats) > 0:
    hat_to_wear = choose_hat(list_of_hats)

Питонический способ сделать это просто использовать тот факт, что списки и последовательности Python оценивают в Правда Если у них есть элементы, а Ложь иначе.

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

if list_of_hats:
    hat_to_wear = choose_hat(list_of_hats)

Делать это таким образом, это конвенция, изложенная в Python’s Pep8 гид по стилю. После того, как вы получили это таким образом, чтобы сделать код немного легче читать и немного менее загромождать.

Заключение

Как уже упоминалось, каждый из них является рефакторированием, что СИГНАЛ может автоматически выполнять для вас. Мы планируем расширять этот блог-сериал и связывая их в качестве дополнительной документации, с целью превращения пришедшего пришествия в отличный ресурс для изучения того, как улучшить свои навыки Python. Вы можете прочитать следующую часть в серии здесь Отказ

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

Объясняя рефакторинги (2 части серии)

Оригинал: “https://dev.to/sourcery/python-refactorings-part-3-4781”