Python装饰器模式:减少涉及内部函数和functools.wrap的代码重复

Python装饰器模式:减少涉及内部函数和functools.wrap的代码重复,python,decorator,python-decorators,Python,Decorator,Python Decorators,我看到了很多关于StackOverflow和其他关于如何编写Python装饰器的文档。他们通常建议使用functools.wrapps和(可能有多个)内部函数。特别复杂的是,如果我想要一个可以用括号调用或不用括号调用的装饰器,即@foo或@foo(bar) 例如,对如何做到这一点有很多见解。然而,对于概念上看似简单的东西,它们都显得相当复杂(额外的条件逻辑或更深层次的函数嵌套)。我最担心的是,在给出的所有示例中,>50%的代码与特定装饰者的行为无关,并且是使用该模式编写的所有装饰者之间共享的样板

我看到了很多关于StackOverflow和其他关于如何编写Python装饰器的文档。他们通常建议使用
functools.wrapps
和(可能有多个)内部函数。特别复杂的是,如果我想要一个可以用括号调用或不用括号调用的装饰器,即
@foo
@foo(bar)

例如,对如何做到这一点有很多见解。然而,对于概念上看似简单的东西,它们都显得相当复杂(额外的条件逻辑或更深层次的函数嵌套)。我最担心的是,在给出的所有示例中,>50%的代码与特定装饰者的行为无关,并且是使用该模式编写的所有装饰者之间共享的样板文件

我所看到的真实例子是和。对我来说似乎有点奇怪,有很多与实际意图无关的样板代码

出于代码可维护性的原因,我理解为什么要使用
functools.wrapps
,但这似乎过于复杂。是否有某种方法来干燥和/或封装此代码?从用户代码的角度来看,我真正关心的似乎只有生成的内部函数的实际主体。我怎样才能把剩下的样板编写一次并永远重复使用呢


提前谢谢

我认为
functools.wrapps
确实代表了样板抽象。我觉得没那么麻烦。我通常在没有它的情况下编写装饰程序,对其进行测试,然后在
functools.wrapps中编译后检查测试是否仍然有效。最多加15分钟

也就是说,我认为没有必要为每个装饰师使用functools包装。对于那些纯粹是内部函数,并且不需要docstring的自解释函数,我通常不会坚持要求它们的装饰执行完全换行

最后,我坚信在
@foo(bar)
是一个选项的情况下,您可以创建
foo
作为一个“装饰工厂”。(即返回修饰符的函数)。然后,您将使用
@foo()
@foo(bar)
。我认为这是处理参数化的装饰器的正确方法。在我看来,decorator始终是接受一个参数并返回该参数的修改和/或包装的函数

PyPI上的、和包抽象出了一些样板代码,超出了
functools.wrapps提供的功能


如果您想同时使用
@foo
@foo(args)
,您的代码必然会产生额外的复杂性,因为
foo(func)
foo(args)(func)
是包装函数的完全不同的方式。我同意Pete的观点,在这种情况下,
@foo()
更清晰。

这是一个关于额外抽象权衡的好观点。我最初没有想到缺点。谢谢感谢您指出,这已经以可重用库的形式存在。