首页 > 解决方案 > 如果装饰器以自下而上的方式堆叠,那么他们为什么不以这种方式执行呢?

问题描述

我试图了解装饰器中函数调用的流程,但无法理解ordinary()函数trace()输出。

由于装饰器以自下而上的方式工作,它们应该以这种方式执行:trace(ordinary())make_list()trace(inner())

根据我的理解,输出应该是这样的:

TRACE: calling ordinary() with (), {}
TRACE: ordinary() returned I am Ordinary
making list of: I am Ordinary
TRACE: calling inner() with (), {}
TRACE: inner() returned ['I', 'am', 'Ordinary']

但输出是这样的:

TRACE: calling inner() with (), {}
TRACE: calling ordinary() with (), {}
TRACE: ordinary() returned I am Ordinary
making list of: I am Ordinary
TRACE: inner() returned ['I', 'am', 'Ordinary']

代码:

import functools

##################### DECORATORS #####################

def uppercase(func):
    def wrapper():
        original_result = func()
        modified_result = original_result.upper()
        return modified_result
    return wrapper

def make_list(func):
    def inner():
        y = func()
        print("making list of: "+y)
        z = y.split()
        return z
    return inner

def trace(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        print(f'TRACE: calling {func.__name__}()'
              f' with {args}, {kwargs}')

        original_result = func(*args,**kwargs)

        print(f'TRACE: {func.__name__}() '
              f'returned {original_result}')
        return original_result
    return wrapper

#################### FUNCTIONS #########################

@trace
@uppercase
def greet():
    return 'hello'

@trace
@make_list
@trace
def ordinary():
    return "I am Ordinary"

################# FUNCTION CALLS ##################

greet()
print('\n')
ordinary()

标签: pythonpython-3.xpython-decorators

解决方案


推荐阅读