English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutorial Básico do Python

Controle de Fluxo do Python

Функции Python

Типы данных Python

Operações de Arquivos do Python

Objetos e Classes do Python

Data e Hora do Python

Conhecimento Avançado do Python

Manual de Referência do Python

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

Os decoradores aceitam uma função, adicionam algumas funcionalidades e a retornam. Neste artigo, você aprenderá como criar decoradores e por que usá-los.

O que são decoradores no Python?

Python tem uma função interessante chamadaDecoradores,pode adicionar funcionalidades ao código existente.

Também chamado deMeta-programação,Porque parte do programa tenta modificar outro parte do programa no tempo de compilação.

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

Чтобы понять декораторы,我们必须 сначала понять некоторые базовые знания Python.

Мы должны принять тот факт, что всё в Python являетсяОбъекты. Названия, которые мы определяем, просто привязаны к этим объектам в качестве идентификаторов.ФункцииЭто также не исключение, они также являются объектами (с свойствами). Разные имена могут быть привязаны к одному и тому же объекту функции.

Это пример.

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

Когда вы запускаете код, эти функции first и second дают одинаковый вывод. Здесь имена first и second указывают на одинаковые объекты функций.

Теперь ситуация стала несколько сложнее, так как можно передавать функции в качестве параметров других функций.

Если вы использовали в Python функции, такие как map, filter и reduce, то вы уже знаете это.

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

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()
# Вывод "Hello"
new()

Здесь, is_returned() - это вложенная функция, которая определяет и возвращает себя каждый раз, когда мы вызываем is_drawn().

В конце концов, мы должны понятьКлонируемые в Python.

Вернёмся к декораторам

Функции и методы называютсяВызываемые,Потому что их можно вызывать.

На самом деле, любая объект, реализующий особый метод __call__(), называется вызываемым. Таким образом, в наиболее базовом смысле, декораторы являются вызываемыми и могут возвращать вызываемые.

В основном, декораторы принимают функцию, добавляют к ней некоторые функции и возвращают её.

def make_pretty(func):
    def inner():
        print("Я был декорирован")
        func()
    возврат inner
def ordinary():
    print("Я обычная функция")

При выполнении следующего кода в shell,

>>> ordinary()
Я обычная функция
>>> # Давайте декорируем эту обычную функцию
>>> pretty = make_pretty(ordinary)
>>> pretty()
Я был декорирован
Я обычная функция

В примере, показанном выше, make_pretty() является декоратором. В шаге назначения.

pretty = make_pretty(ordinary)

Функция ordinary() была декорирована, и возвращенная функция была命名为 pretty.

Мы можем увидеть, что decorator функция добавляет некоторые новые функции в исходную функцию. Это похоже на упаковку подарка. Декоратор играет роль упаковщика. Свойства подарка (внутри) не изменяются. Но теперь он выглядит красиво (с момента упаковки).

Обычно мы декорируем функцию и заново присваиваем ее

ordinary = make_pretty(ordinary).

Это распространенная конструкция, поэтому Python имеет синтаксис для ее упрощения.

Мы можем использовать символ @ вместе с именем декораторной функции и поместить его над определением функции, которую мы хотим декорировать. Например,

@make_pretty
def ordinary():
    print("Я обычная функция")

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

def ordinary():
    print("Я обычная функция")
ordinary = make_pretty(ordinary)

Это просто синтаксический сахар для реализации декоратора.

Декорировать функцию параметрами

Этот декоратор прост и подходит только для функций без параметров. Что если наши функции имеют такие параметры?

def divide(a, b):
    return a/b

Эта функция имеет два параметра:aиb. Мы знаем, что если мы我们将bЕсли передается 0, то возникает ошибка.

>>> divide(2,5)
0.4
>>> divide(2,0)
Traceback (последний вызов в конце):
...
ZeroDivisionError: деление на ноль

Теперь давайте создадим декоратор, чтобы проверить, приведет ли это к ошибке.

def smart_divide(func):
   def inner(a,b):
      print("Я хочу сделать деление", a, "и", b)
      if b == 0:
         print("О, не могу поделить")
         return
      return func(a,b)
   возврат inner
@smart_divide
def divide(a,b):
    return a/b

Если arises ошибка, новая реализация вернет None.

>>> divide(2,5)
Я хочу сделать деление 2 и 5
0.4
>>> divide(2,0)
Я хочу сделать деление 2 и 0
Ой! Не можно делить

Таким образом, мы можем декорировать функции с параметрами.

Шарпый наблюдатель заметит, что параметры вложенной функции в декораторе inner() такие же, как и параметры декорируемой функции. учитывая это, теперь мы можем сделать универсальный декоратор, который может использовать любое количество параметров.

В Python это магия достигается через completion function(*args, **kwargs). Таким образом, args — это позиционные параметрыТупльа kwargs — это ключевые параметрыСловарь. Пример такого декоратора —

def works_for_all(func):
    def inner(*args, **kwargs):
        print("Я могу декорировать любую функцию")
        возврат func(*args, **kwargs)
    возврат inner

Связанные декораторы Python

Можем ли мы связать несколько декораторов в Python.

Это означает, что функция может быть декорирована несколькими (или одинаковыми) декораторами. Нам нужно только поместить декораторы над нужной функцией.

def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    возврат inner
def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    возврат inner
@star
@percent
def printer(msg):
    print(msg)
printer("Привет")

Это даст вывод.

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Привет
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

верхней грамматике,

@star
@percent
def printer(msg):
    print(msg)

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

def printer(msg):
    print(msg)
printer = star(percent(printer))

Порядок链接 декораторов очень важен. Если мы будем использовать обратный порядок,

@percent
@star
def printer(msg):
    print(msg)

Выполнение будет производиться

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Привет
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%