«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Python: интересные шаблоны кода

Python: интересные шаблоны кода

Опубликовано 8 ноября 2024 г.
Просматривать:321

Python: Interesting Code Patterns

Я в основном работаю с Python и почти ежедневно проверяю код. В нашей кодовой базе форматирование и линтинг выполняются заданиями CI с использованием black и mypy. Итак, мы фокусируемся только на изменениях.

Работая в команде, ты уже знаешь, какой код ожидать от конкретного члена команды. Обзоры кода становятся интересными, когда к команде присоединяется новый человек. Я говорю «интересно», поскольку у каждого есть какой-то стиль кодирования, который они используют бессознательно; в хорошую или плохую сторону! Как будто у меня есть немного,

  1. Установка значения необязательного типа. Обычно эти переменные являются частью подписи
# I used (long back) to do

def func(a: int, b: Optional[list] = None, c: Optional[Dict] = None):

    if b is None:
       b = []
    if c is None:
       c = {}

# Instead I do

def func(a: int, b: Optional[list] = None, c: Optional[Dict] = None):

    b = b or []
    c = c or {}
  1. Обработка простых операторов if..elif..else (до 3-4) с помощью dict

Это простой вариант использования, когда вы возвращаете строку или вызываете функцию на основе некоторого значения.

Примечание: начиная с версии 3.10 вместо этого следует использовать match.

Вместо того, чтобы делать,

def get_number_of_wheels(vehicle: str):
    if vehicle == "car":
        wheels = 2
    elif vehicle == "bus":
        wheels = 6
    elif vehicle == "bicycle":
        wheels = 2
    else:
        raise ...

# I prefer doing, 

def get_number_of_wheels(vehicle: str):
    return {
       "car": 2,
       "bus": 6,
       "bicycle": 2
    }[vehicle]       # Raise is now KeyError

Выше приведено несколько примеров. Люди, просматривающие мой код, найдут еще примеры.

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

Код представляет собой декоратор, который что-то делает с параметрами. Давайте напишем простой (бесполезный) декоратор, который будет печатать количество аргументов и kwargs, с помощью которых была вызвана функция/метод.

def counter(is_cls_method: bool = False):
    """ print number of args & kwargs for func/method """
    def outer(f):
        def inner(*args, **kwargs):
            args_cnt = len(args)
            kwargs_cnt = len(kwargs)
            print(f"{f.__name__} called with {args_cnt=} & {kwargs_cnt=}")
            return f(*args, **kwargs)
        return inner
    return outer

@counter()
def test1(a, b, c):
    pass

class A:
    @counter(is_cls_method=True)
    def test1(self, a, b, c):
        pass


print("function")
test1(1, 2, c=3)
test1(a=1, b=2, c=3)

print("method")
a = A()
a.test1(1, 2, 3)
a.test1(1, b=2, c=3)

При запуске этого кода вы должны увидеть

function
test1 called with args_cnt=2 & kwargs_cnt=1
test1 called with args_cnt=0 & kwargs_cnt=3

method
test1 called with args_cnt=4 & kwargs_cnt=0
test1 called with args_cnt=2 & kwargs_cnt=2

Он работает нормально, но для методов он также считает себя. так что давай это исправим!

def counter(is_cls_method: bool = False):
    def outer(f):
        def inner(*args, **kwargs):
            args_cnt = len(args)

            if is_cls_method:   # Check added
               args_cnt -= 1    # Reduced count by 1

            kwargs_cnt = len(kwargs)
            print(f"{f.__name__} called with {args_cnt=} & {kwargs_cnt=}")
            return f(*args, **kwargs)
        return inner
    return outer

Это простое предложение if, но новый разработчик сделал что-то еще, интересное использование логического значения.

Я показываю только измененный код...

   args_cnt = len(args[is_cls_method:])

Решение намного лучше, чем использование if, поскольку bool в Python — это просто int. Исходный код был немного длиннее, и заметить это небольшое изменение неочевидно, а также базу кода, используемую пользователями, которые являются базовыми пользователями Python. И если вам нужно угадать, что делает строка, я думаю, вам следует изменить ее, чтобы сделать это очевидным.

Что вы думаете по этому поводу? Используете ли вы логическое значение в качестве индекса?
Есть ли у вас еще подобные шаблоны Python?

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/ninadmhatre/python-interesting-code-patterns-dh3?1. Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить их.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3