Python装饰器应该多久使用一次?

Rex*_*exE 3 python django decorator

我最近开始尝试使用Python装饰器(以及高阶函数),因为看起来它们可能会使我的Django单元测试更加简洁.例如,而不是写:

def visit1():
    login()
    do_stuff()
    logout()
Run Code Online (Sandbox Code Playgroud)

我可以改为做

@handle_login
def visit1():
    do_stuff()
Run Code Online (Sandbox Code Playgroud)

然而,经过一些实验,我发现装饰器并不像我希望的那么简单.首先,我在不同的例子中找到了不同的装饰器语法,直到我了解到装饰器在接受参数时表现得非常不同.然后我尝试装饰一个方法,并最终知道它不起作用,因为我首先必须通过添加方法将我的装饰器变成描述符__get__.在整个过程中,我最终混淆了几次,但仍然发现调试这个"装饰"代码比通常用于Python更复杂.我现在正在重新评估我的代码中是否真的需要装饰器,因为我最初的动机是节省一些打字,而不是因为有任何真正需要高阶函数的东西.

所以我的问题是:装饰者应该被大量使用还是少量使用?避免使用它们是否更加Pythonic?

Ale*_*lli 12

装饰师在他们的位置很好,绝对不能避免 - 适当时;-).我看到的基本上是"OK,所以当你的意思的问题,他们适当"?

在某些类的某些但不是所有方法周围添加一些前缀和/或后缀代码就是一个很好的例子.如果是所有方法,包装所有方法的装饰器将比@thisonetoo无休止地重复更好;-).如果它曾经是一个蓝色的月亮,那么不值得重构包装(装饰者或其他).在中间,有一个很大的地方,装饰者确实非常合适.

它归结为编程的黄金法则之一 - 干,因为不要重复自己.当你看到你的代码变得重复时,你应该重构重复 - 装饰器是一个很好的工具,虽然它们远非唯一的(辅助方法和函数,自定义元类,生成器和其他迭代器,上下文管理器) ... 我们在过去几年中添加到Python中的许多功能最好被认为是DRY-helpers,更容易和更平滑的方法来分解这种或那种频繁的重复形式!).

如果没有重复,就没有真正的重构要求,因此(特别是)没有真正需要装饰者 - 在这种情况下,YAGNI(Y'Ain't Gonna Need It)可以胜过DRY ;-).