Python 如何扩展库';谁是装修工?

Python 如何扩展库';谁是装修工?,python,decorator,python-decorators,Python,Decorator,Python Decorators,我想扩展一个图书馆的装饰器。我知道我可以给两个装饰师打电话: @my_decorator @lib_decorator def func(): pass 但我希望避免每次都必须将@lib\u decorator传递给每个函数。我希望我的decorator使用lib\u decorator自动装饰func()。我该怎么做?它们可以嵌套吗?您可以将库的装饰器合并到您的库中。对于简单的、无参数的装饰器,它相当直截了当: def my_decorator(): @lib_decorat

我想扩展一个图书馆的装饰器。我知道我可以给两个装饰师打电话:

@my_decorator
@lib_decorator
def func():
    pass

但我希望避免每次都必须将
@lib\u decorator
传递给每个函数。我希望我的decorator使用
lib\u decorator
自动装饰
func()
。我该怎么做?它们可以嵌套吗?

您可以将库的装饰器合并到您的库中。对于简单的、无参数的装饰器,它相当直截了当:

def my_decorator():
    @lib_decorator  # <--- Just include the lib's decorator here
    def inner:
        func(*args, **kwargs)
    return inner
然后使用lib decorator装饰内部函数:

def my_decorator(arg):
    def wrapper(func):

        @lib_decorator  # <--- Just include the lib's decorator here
        def inner(*args, **kwargs):
            func(*args, **kwargs)

        return inner

    return wrapper

您可以轻松改造您的装饰:

@my_decorator
@lib_decorator
def func():
    pass
对于这种更简单的装饰,使用函数组合:

my_composed_decorator = lambda func: my_decorator(lib_decorator(func))

@my_composed_decorator
def func():
    pass

两个示例decorator都有一个额外的层,仅当您希望支持向decorator传递参数时才需要该层(例如
@my_decorator(“foo”)
)。对于问题中未被用户调用的装饰器(仅命名,例如,
@my\u decorator
),您不需要该层。谢谢,@Blckknght。我相信我的示例decorator适用于函数需要参数的情况,而不是decorator(例如,
func(“foo”)
,不是吗?不管怎样,我承认问题中的示例不需要它,我只是想提供最完整的解决方案,以防它与其他人相关。是的,它们支持带参数的函数,但我要说的是,
@my_decorator
无法应用它们。由于额外的层,您eed
@my_decorator()
(调用decorator工厂,返回decorator;
@
语法对函数调用的decorator,返回内部包装函数)。如果在函数版本中去掉
包装器
,它将在没有括号的情况下工作。类版本有点棘手,因为不是所有的修饰符都能很好地处理方法。您可能希望
\u调用
执行
返回库修饰符(self.func)(*args,**kwargs)
@Blckknght,谢谢。这有助于我把事情弄清楚。我没有抓住
@my\u decorator
@my\u decorator()之间的区别
在我之前阅读的所有文章中。如何将
arg
传递给
lib_decorator
?我喜欢你展示的函数组合方法,因为它回忆起,decorator确实是函数返回函数,可以这样处理,而不必使用
@something
糖。
@my_decorator
@lib_decorator
def func():
    pass
my_composed_decorator = lambda func: my_decorator(lib_decorator(func))

@my_composed_decorator
def func():
    pass