装饰多个Python函数

装饰多个Python函数,python,python-decorators,Python,Python Decorators,假设我有很多对互补函数: def comp_func1(arg1, arg2): return f"comp_func1 {arg1} {arg2}" def func1(arg1, arg2, flag=True): if flag: return f"func1 {arg1} {arg2}" else: return comp_func1(arg1, arg2) def comp_func2(

假设我有很多对互补函数:

def comp_func1(arg1, arg2):
    return f"comp_func1 {arg1} {arg2}"

def func1(arg1, arg2, flag=True):
    if flag:
        return f"func1 {arg1} {arg2}"
    else:
        return comp_func1(arg1, arg2)

def comp_func2(arg1, arg2):
    return f"comp_func2 {arg1} {arg2}"

def func2(arg1, arg2, flag=True):
    if flag:
        return f"func2 {arg1} {arg2}"
    else:
        return comp_func2(arg1, arg2)
本质上,对于每个函数funcX,如果flag==True,那么它将返回函数细节,但是如果flag==False,那么它将调用其互补函数comp_funcX,它将返回互补函数细节

不必在每个funcX中使用if/else语句,是否可以使用decorator来清理或简化此代码?大致如下:

def decorator():
    """
    Check the `flag` and choose whether to call the complementary function
    """
    def wrapper():
        if flag:
            return func(arg1, arg2)
        else:
            return comp_func(args, arg2) 
    return wrapper

def comp_func1(arg1, arg2):
    return f"comp_func1 {arg1} {arg2}"

@decorator(comp_func1)
def func1(arg1, arg2, flag=True):
    return f"func1 {arg1} {arg2}"

def comp_func2(arg1, arg2):
    return f"comp_func2 {arg1} {arg2}"

@decorator(comp_func2)
def func2(arg1, arg2, flag=True):
    return f"func2 {arg1} {arg2}"
像这样的

def some_decorator(comp_function):
    def decorator_with_argument(function):
        def wrapper(*args, **kwargs):
            if kwargs.get("flag", False):
                return function(*args, **kwargs)
            else:
                return comp_function(*args, **kwargs)
        return wrapper
    return decorator_with_argument


def comp_func1(arg1, arg2, *_, **__):
    return f"comp_func1 {arg1} {arg2}"


@some_decorator(comp_func1)
def func1(arg1, arg2, *_, **__):
    return f"func1 {arg1} {arg2}"

包装器函数通常采用*args和**kwargs,因此它更为通用。

稍微不同的方法是使用一个简单的包装器函数,而不是一个成熟的装饰器。将所有函数和补充函数打包到相应的列表中,并使用索引通过包装器调用您的函数:

funcs=[func1,func2,…] comps=[comp_func1,comp_func2,…] def包装器,arg1,arg2,标志: 如果标志: 返回函数[i-1]arg1,arg2 其他: 返回组件[i-1]arg1、arg2 现在要调用func1,只需调用:

wrapper(1, arg1, arg2, flag)

这是基于第二个代码块中实现的函数。i、 e.每个函数返回其相应的数据-其中没有标志条件。

除了装饰器中缺少的一些细节外,您没有说明它有什么问题。看来你在寻找替代方案……啊,我写答案太慢了!不过,您已经翻转了函数和comp_函数。一些_decorator应该将comp_函数作为参数,而带有_参数的decorator_应该作为函数。与其在包装器中硬编码func1的参数,我建议将func1中的flag改为只包含关键字的参数:func1arg1,arg2,*,flag=True:然后将包装器改为:def wrapper*args,**kwargs:带有kwargs.getflag,相反,if语句为False。