Skip to main content
 首页 » 编程设计

Python——函数装饰器导致函数被调用两次

2025年05月04日14pengyingh

我在编写测试代码的一些单元测试中使用函数装饰器。然而,我发现这个装饰器导致函数被调用两次(因此打印它的输出两次)。

我在一些函数返回错误的返回值后发现了这个错误,而错误的返回值只有在函数被调用两次时才会发生。

#!/usr/bin/env python3 
 
def decorate(func): 
    @wraps(func) 
    def inner(*args, **kwargs): 
        print("#" * 40) 
        print("Testing function {}".format(func.__name__)) 
        print("Arguments passed: {} ".format(args)) 
        print("Begin output of {}".format(func.__name__)) 
        print("#" * 40) 
        try: 
            func(*args, **kwargs) 
        except Exception as e: 
            print("Error occured: {}".format(e)) 
 
        print("#" * 40) 
        print("End of output of {}".format(func.__name__)) 
        print("#" * 40) 
        print("\n" * 5) 
        return func(*args,**kwargs) #Error happens on this line here 
    return inner 
 
#Add decorator to function definition.  
@decorate 
def asdf(): 
    print("THIS SHOULD PRINT ONCE") 
 
#Call function 
 
asdf() 

输出(与复制的间距完全相同):

######################################## 
Testing function asdf 
Arguments passed: () 
Begin output of asdf 
######################################## 
THIS SHOULD PRINT ONCE 
######################################## 
End of output of asdf 
######################################## 
 
 
 
 
 
 
THIS SHOULD PRINT ONCE 

我想要的输出:

######################################## 
Testing function asdf 
Arguments passed: () 
Begin output of asdf 
######################################## 
THIS SHOULD PRINT ONCE 
######################################## 
End of output of asdf 
######################################## 

我试图消除函数的第二次调用。我知道我的错误在于装饰器,我只是找不到它。

请您参考如下方法:

请注意,您从装饰器内部调用该函数两次:

  • 一旦进入 try/except block 。
  • 并在返回语句中一次。

您可能希望将第一个调用(try block 中的调用)更改为:

res = func(*args, **kwargs) 

然后简单地:

return res 

编辑:(根据@DanielRoseman 的评论)

因为你没有从 except block 中引发或返回,你必须在那里分配 res (在 except 内)或者或者在装饰器的开头将其预定义为 None(或适合您的程序的任何值)。