python装饰器包装两次



意外遇到python decorator的一个奇怪问题,基本上当我直接调用decorator函数时,被包装的原始函数被包装了两次。

一些简单的代码来显示问题:

def my_deco(f):
def wrapper(*args):
print('some code before')
f(*args)
print('some code after')
return wrapper
@my_deco
def original_func(text):
print   (f'original func print {text}')

然后命令1(:

original_func('hello')

将打印(顺便说一句,这是正确的(:

some code before
original func print hello
some code after

但命令2(:

my_deco(original_func)('hello')

将在下面打印:

some code before
some code before
original func print hello
some code after
some code after

预期两个命令之间的结果相同,但后一个命令似乎将原始函数包装了两次。当我在没有括号的情况下运行这两个命令时,它们都正确地指向包装器函数,但使用括号执行后的结果不同。

我用以下逻辑说服了自己,但仍然感到不舒服,所以我正在寻找对我的想法的评论或纠正:

命令1(:调用original_func->my_deco->包装器->包装+original_func执行

命令2(:调用my_deco->包装器->包装+original_func执行(它是包装版本(

因此,看起来命令1(中的original_func保持为"0";原始的";无包装;并且命令2中的original_func(是"0";"包裹";版本

提前谢谢。

当你定义original_func时,你使用了一个decorator,所以python对它进行了包装。在命令2中,你自己再次包装它,所以结果是函数被包装了两次
如果运行以下操作,输出应该是正确的:

def original_func(text):
print   (f'original func print {text}')
my_deco(original_func)('hello')

这里有一个简单的例子:

创建装饰器:

def decor(func):
def wrapper(num1, num2):
print('before')
func(num1, num2)
print('after')
return wrapper

调用decorator。此代码不正确,因为您调用了decorator两次,即@decorat和decorat(add(:

@decor
def add(num1, num2):
print(num1 + num2)
add = decor(add)  ## This line will cause it to print a second time. Remove it.
add(3, 88)

调用decorator。此代码正确:

@decor
def add(num1, num2):
print(num1 + num2)
add(3, 88)

最新更新