双重装饰,为什么我的一个封闭函数没有被执行?

2024-09-28 05:25:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图理解如何在一个函数上使用两个decorator,代码如下:

def fxn(func):
    print("fxn_outer 1")
    def fxn_inner(*args, **kwargs):
        print("fxn_inner 1")
    return fxn_inner

def fxn2(func):
    print("fxn_outer 2")
    def fxn_inner2(*args, **kwargs):
        print("fxn_inner 2")
    return fxn_inner2

@fxn
@fxn2
def fxn3 (a, b):
    print(a + b)

fxn3(1, 2)

我不明白为什么fxn_inner在上面的代码中执行,而fxn_inner2没有执行。你知道吗

输出为:

fxn_outer 2
fxn_outer 1
fxn_inner 1

当我期望以下输出时:

fxn_outer 2
fxn_outer 1
fxn_inner 1
fxn_inner 2

为什么当我同时调用两个包装函数时,它们中只有一个被执行?你知道吗


Tags: 函数代码returndefargsdecoratorkwargsfunc
2条回答

这是因为您没有在decorator的主体中执行给定给decorator的函数(包装函数)。因此,执行在第一个装饰器的主体中停止(即fxn_inner)。你知道吗

通常,您对decorator所做的是调用(调用)decorator中的decorated函数,即

def fxn(func):
    print("fxn_outer 1")
    def fxn_inner(*args, **kwargs):
        print("fxn_inner 1")
        func(*args, **kwargs)
    return fxn_inner

def fxn2(func):
    print("fxn_outer 2")
    def fxn_inner2(*args, **kwargs):
        print("fxn_inner 2")
        func(*args, **kwargs)
    return fxn_inner2

@fxn
@fxn2
def fxn3 (a, b):
    print(a + b)

fxn3(1, 2)

decorator只是调用函数和重新分配名称的语法糖,因此您所做的工作等效于:

fxn3 = fxn2(fxn3)
fxn3 = fxn(fxn3)

fxn3(1, 2)

发生了什么?在第一次赋值之后,您有fxn3 == fxn2_inner。 第二行之后是fxn3 == fxn_inner。你知道吗

但是fxn(和fxn_inner)的定义只是扔掉了参数func!因此,当您调用fxn3(1,2) == fxn_inner(1, 2)时,不会看到它被调用。你知道吗

如果要调用原始函数,应在*_inner函数内调用func

def fxn(func):
    print("fxn_outer 1")
    def fxn_inner(*args, **kwargs):
        print("fxn_inner 1")
        return func(*args, **kwargs)
    return fxn_inner

def fxn2(func):
    print("fxn_outer 2")
    def fxn_inner2(*args, **kwargs):
        print("fxn_inner 2")
        return func(*args, **kwargs)
    return fxn_inner2

相关问题 更多 >

    热门问题