Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Python

Декораторы в Python: улучшайте функции экспертными техниками

Декораторы в Python

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

Видео: @Декораторы в Python

Декораторы в Python

Декораторы Python — мощный метапрограмминговый инструмент, позволяющий добавлять поведение функциям или классам в момент определения. Поскольку в Python всё — объекты, включая функции и классы, декораторы работают, принимая один вызываемый объект, оборачивая его в другой и возвращая новый вызываемый.


Предварительные знания для изучения декораторов

Прежде чем углубляться, вы должны быть комфортны с тем, что в Python функции — объекты первого класса. Имена — просто ссылки, привязанные к объектам; одна и та же функция может ссылаться несколькими именами.

def first(msg):
    print(msg)
first("Hello")
second = first
second("Hello")

Вывод

Hello
Hello

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

def inc(x):
    return x + 1
def dec(x):
    return x - 1
def operate(func, x):
    result = func(x)
    return result

Использование:

>>> operate(inc, 3)
4
>>> operate(dec, 3)
2
def is_called():
    def is_returned():
        print("Hello")
    return is_returned
new = is_called()
new()

Вывод

Hello

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


Возвращаемся к декораторам

В Python декоратор — это просто вызываемый объект, принимающий функцию (или другой вызываемый) и возвращающий новый вызываемый. Возвращённая функция обычно оборачивает оригинальную, добавляя или изменяя функциональность до или после вызова.

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner
def ordinary():
    print("I am ordinary")

Пример использования:

>>> ordinary()
I am ordinary
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

Паттерн декоратора сохраняет семантику оригинальной функции нетронутой, пока расширяя её. Чтобы избежать ручного переприсваивания, Python предоставляет синтаксический сахар с символом @:

@make_pretty
def ordinary():
    print("I am ordinary")

Это эквивалентно:

def ordinary():
    print("I am ordinary")
ordinary = make_pretty(ordinary)

Декорирование функций с параметрами

Многие декораторы должны обрабатывать произвольные аргументы. Синтаксис *args и **kwargs позволяет захватывать любые позиционные или именованные аргументы и передавать их без изменений.

def works_for_all(func):
    def inner(*args, **kwargs):
        print("I can decorate any function")
        return func(*args, **kwargs)
    return inner

Обработка граничных случаев — ещё одно частое применение декораторов. Например, защита от деления на ноль:

def smart_divide(func):
    def inner(a, b):
        print("I am going to divide", a, "and", b)
        if b == 0:
            print("Whoops! cannot divide")
            return
        return func(a, b)
    return inner
@smart_divide
def divide(a, b):
    print(a / b)

Использование:

>>> divide(2, 5)
I am going to divide 2 and 5
0.4
>>> divide(2, 0)
I am going to divide 2 and 0
Whoops! cannot divide

Цепочки декораторов в Python

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

def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner
def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner
@star
@percent
def printer(msg):
    print(msg)

Результат:

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

Смена порядка меняет окружающие паттерны, демонстрируя, как наложение декораторов влияет на поведение.

Python

  1. Освоение типов данных в Python: практическое руководство
  2. Мастерство операторов Python: Полное руководство
  3. Оператор pass в Python: практическое руководство
  4. Аргументы функций в Python: позиционные, именованные и параметры по умолчанию
  5. Lambda-функции в Python: практическое руководство по анонимным функциям
  6. Освоение лямбда-функций Python: практические примеры и лучшие практики
  7. Функция abs() в Python: вычисление абсолютных значений для чисел и комплексных чисел
  8. Функция round() в Python: подробное объяснение с практическими примерами
  9. Освоение функции range() в Python: от основ к продвинутым сценариям
  10. Освоение функции map() в Python: синтаксис, примеры и лучшие практики