gpt4 book ai didi

python - 不带括号调用装饰器(不更 retrofit 饰器定义)

转载 作者:行者123 更新时间:2023-12-01 07:00:42 26 4
gpt4 key购买 nike

假设我有以下装饰器。 (重复一个函数n次)

def repeat(num_times=4):
def decorator_repeat(func):
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
for _ in range(num_times):
value = func(*args, **kwargs)
return value
return wrapper_repeat
return decorator_repeat

现在,它确实有一个默认值4,但是,即使我想用默认值调用它,我仍然必须按如下方式调用它

@repeat()
def my_function():
print("hello")

而不是

@repeat
def my_function():
print("hello")

现在,我可以将装饰器的定义更改为

def repeat(_func=None, *, num_times=2):
def decorator_repeat(func):
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
for _ in range(num_times):
value = func(*args, **kwargs)
return value
return wrapper_repeat

if _func is None:
return decorator_repeat
else:
return decorator_repeat(_func)

如果我愿意的话,可以启用不带参数调用它的功能。

但是,是否可以在不改变装饰器的代码的情况下,而是通过定义另一个装饰器来实现这一点呢?

即我想定义一个装饰器enable_direct这样我就可以添加 @enable_direct到我的装饰器定义并具有相同的效果。 (即如下)

@enable_direct
def repeat(num_times=4):
def decorator_repeat(func):
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
for _ in range(num_times):
value = func(*args, **kwargs)
return value
return wrapper_repeat
return decorator_repeat

注意:

我知道 How to create a Python decorator that can be used either with or without parameters? 中提到的解决方案

该问题中的定义具有不同的签名,如果重新开始,则可以遵循该模式。然而,假设我有 20-30 个这样的装饰器定义(3 级嵌套)。我希望所有这些都能够在没有括号的情况下调用。def repeat语句没有函数参数。该问题中的函数有 2 级嵌套,而我的函数有 3 级。我想问是否可以使用这样的装饰器定义(即用括号调用)而不更改函数定义。那里接受的答案有不同的签名,因此不符合这个问题的要求。

注2:在尝试那里给出的双重换行的定义之前,我没有问这个问题。不带括号调用它会返回另一个函数(如果函数的签名如所描述的那样)。

最佳答案

你在这里:

import functools


def enable_direct(decorator):
@functools.wraps(decorator)
def wrapper(*args, **kwargs):
f = args[0]
if callable(f):
return decorator()(f) # pass the function to be decorated
else:
return decorator(*args, **kwargs) # pass the specified params
return wrapper


@enable_direct
def repeat(num_times=4):
def decorator_repeat(func):
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
for _ in range(num_times):
value = func(*args, **kwargs)
return value
return wrapper_repeat
return decorator_repeat


@repeat
def my_func(name):
print(name)

@repeat(2)
def my_func2(name):
print(name)


print(my_func)
print(my_func2)

my_func("Gino")
my_func2("Mario")

哪个产生

<function my_func at 0x7f629f091b70>
<function my_func2 at 0x7f629f091bf8>
Gino
Gino
Gino
Gino
Mario
Mario

关于python - 不带括号调用装饰器(不更 retrofit 饰器定义),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58642666/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com