синтаксис функции декоратора python - PullRequest
0 голосов
/ 02 октября 2018

Я изучаю функции декоратора на python и оборачиваюсь вокруг синтаксиса @.

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

def duplicator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        func(*args, **kwargs)
    return wrapper

Если я правильно понимаю, кажется, что:

@duplicator
def print_hi():
    print('We will do this twice')

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

print_hi = duplicator(print_hi)
print_hi()

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

Используя пример отсюда: https://realpython.com/primer-on-python-decorators/

def repeat(num_times):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat
    return decorator_repeat

Я могу позвонить по этому номеру:

@repeat(num_times=4)
def print_hi(num_times):
    print(f"We will do this {num_times} times")

Однако это, безусловно, не эквивалентноto:

print_hi = repeat(print_hi)

Поскольку у нас есть дополнительный аргумент num_times.

Что я неправильно понимаю?Это эквивалентно:

print_hi = repeat(print_hi, num_times=4)

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

repeat(num_times) возвращает функцию, и эта функция используется для оформления print_hi.

@repeat(num_times=4)
def print_hi(num_times):
    ...

составляет

f = repeat(num_times)
print_hi = f(print_hi)

Функция, которую возвращает repeat, равна decorator_repeat, который украшает print_hi.

0 голосов
/ 02 октября 2018

В случае декоратора repeat эквивалент равен:

print_hi = repeat(num_times=4)(print_hi)

Здесь repeat принимает аргумент num_times и возвращает закрытие decorator_repeat, которое само принимает func аргументов и возвращает закрытие wrapper_repeat.

...