Почему второй декоратор не заканчивает свою работу до завершения работы первого декоратора? - PullRequest
0 голосов
/ 06 февраля 2020

Я новичок ie.

Теперь я застрял с декоратором.

Проблема в том, почему второй декоратор не заканчивает свою работу, а делает паузу , И почему после окончания 1-го декоратора, 2-й декоратор заканчивает sh свою работу?

Функция

def document_it(func):
    def new_function(*args, **kwargs):
        print('Running function:', func.__name__) 
        print('Positional arguments:', args)
        print('Keyword arguments:', kwargs)
        result = func(*args, **kwargs)
        print('Result:', result)
        return result
    return new_function

1-я Ситуация

@document_it
def add_ints(a, b):
    return a + b

add_ints(3, 5)

1-я Ситуация результат: Смотри внимательно Бегущая функция!

Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Result: 8

2-я ситуация !!!!!!!!!!!

@document_it
@document_it
def add_ints(a, b):
    return a + b

add_ints(3, 5)

2-я ситуация Результат: Смотри внимательно. Функция запуска: new_function - это ПЕРВЫЙ !!!!

Running function: new_function #seems 2nd's
Positional arguments: (3, 5) #seems 2nd's
Keyword arguments: {} #seems 2nd's
Running function: add_ints #seems 1st's
Positional arguments: (3, 5) #seems 1st's
Keyword arguments: {} #seems 1st's
Result: 8 #seems 1st's
Result: 8 #seems 2nd's

Почему 2-й декоратор не закончил sh свою работу (2-й декоратор не распечатал свой Результат), но внезапно появился 1-й декоратор?

1 Ответ

0 голосов
/ 06 февраля 2020

Украшение - просто синтактика c сахар для функционального применения. Ваш оригинальный код

@document_it
@document_it
def add_ints(a, b):
    return a + b

add_ints(3, 5)

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

def add_ints(a, b):
    return a + b

add_ints = document_it(document_it(add_ints))

add_ints(3, 5)

Каждый вызов декоратора создает новую функцию, которая оборачивает и вызывает декорированную функцию.


Если вы слегка измените свой декоратор:

def document_it(func):
    def new_function(*args, **kwargs):
        print('Running function:', func.__name__) 
        print('Positional arguments:', args)
        print('Keyword arguments:', kwargs)
        <b>print('Function id: ', id(func))</b>
        result = func(*args, **kwargs)
        print('Result:', result)
        return result
    return new_function

Вы увидите, что каждая вызываемая функция отличается: add_ints теперь действительно представляет собой стек из 3 функций, состоящий из оригинального add_ints и функции, возвращаемые каждым использованием декоратора.

>>> print(id(add_ints))
<b>4558720608</b>
>>> add_ints(3, 5)
Running function: new_function
Positional arguments: (3, 5)
Keyword arguments: {}
Function id:  <b>4558720032</b>
Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Function id:  <b>4558719888</b>
Result: 8
Result: 8

4558719888 - это ваша оригинальная, неокрашенная функция, которая фактически добавляет два числа; 4558720032 - это new_function, созданный «внутренним» декоратором, а 4558720608 - это new_function, созданный «внешним» декоратором, с которым теперь связано имя add_ints.

...