gpt4 book ai didi

python - 允许函数接受任意参数的装饰器

转载 作者:行者123 更新时间:2023-11-28 21:51:17 25 4
gpt4 key购买 nike

如何编写装饰器,使装饰函数可以接受(并忽略)任意参数?

我有一些这样的功能:

def foo(x):
return x

def foo2(x, y):
if bar(y):
return x
else:
return x + 1

def foo3(x, y, z):
...

foo() 可以根据x 计算给定x 的返回值,但是foo2() 需要另一个参数,foo3() 需要第三个参数。我在别处有一个方法,除其他外,它根据用户指定的参数调用 foo()foo2() 等。

现在,该方法只是使用 getattr(user_arg) 获取适当的函数,并使用 xyz。为了避免错误数量的参数导致 TypeError,foo 函数都使用 *args 定义,如下所示:

def foo(x, *args):
return x

但我只想有一个装饰器来避免在每个 foo 函数定义中包含 *args 。有没有办法做到这一点?或者您能否建议一种更好的方式来组织此代码?

一种方法是这样写方法:

if user_arg == 'foo':
foo(x)
elif user_arg == 'foo2':
foo2(x, y)
elif user_arg == 'foo3':
foo3(x, y, z)

但我真的很想避免这种情况,因为有很多 foo 函数,而且我想让添加新的 foo 成为可能无需向该方法添加另一个分支即可运行。

编辑:澄清一下,我不需要根据参数数量调用不同的foo 函数。调用哪个 foo 函数是任意的(用户指定的)。

def foo3(x, y, z):
return x + y + z

def foo4(x, y, z):
return x + y - z

最佳答案

您可以使用 inspect.getargspec确定装饰函数采用哪些参数:

import functools
import inspect

def ignore_extra_arguments(func):
args, varargs, kwvarargs, defaults = inspect.getargspec(func)
@functools.wraps(func)
def wrapper_func(*wrapper_args, **wrapper_kwargs):
if varargs is None:
# remove extra positional arguments
wrapper_args = wrapper_args[:len(args)]
if kwvarargs is None:
# remove extra keyword arguments
wrapper_kwargs = {k: v for k, v in wrapper_kwargs.iteritems() if k in args}
return func(*wrapper_args, **wrapper_kwargs)
return wrapper_func

这可以通过提升 if 检查 wrapper_func 来稍微优化,但代价是编写更多代码。

关于python - 允许函数接受任意参数的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30564502/

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