【问题标题】:How can I pack several decorators into one?如何将多个装饰器打包成一个?
【发布时间】:2011-01-12 01:49:44
【问题描述】:

每个函数都有几个装饰器,有没有办法将它们打包成一个?

@fun1
@fun2
@fun3
def do_stuf():
    pass

改为:

@all_funs #runs fun1 fun2 and fun3, how should all_funs look like?
def do_stuf():
    pass

【问题讨论】:

  • @Torsten Marek:有任何理由或证据证明这一说法?
  • @S.Lott:这个问题专门关于编写一个封装多个装饰器调用的函数,另一个为什么装饰器上的装饰器不起作用。也许可以从另一个问题中推断出这个问题的答案,但并不简单,尤其是对于那些在装饰器概念上苦苦挣扎的人来说。
  • 它们似乎都是“链接”装饰器来创建复合装饰器。

标签: python decorator


【解决方案1】:

装饰器原则上只是语法糖:

def do_stuf():
    pass

do_stuf = fun1(do_stuf)

所以在你的 all_fun 中,你需要做的就是将函数包装在同一种装饰器链中:

def all_funs(funky):
    return fun1(fun2(fun3(fun4(funky)))

如果你有装饰器的参数,事情会变得有点(但只是一点点)复杂。

【讨论】:

    【解决方案2】:

    也可以编写一个支持装饰器链接的通用装饰器:

    def fun1(f):
        print "fun1"
        return f
    
    def fun2(f):
        print "fun2"
        return f
    
    def fun3(f):
        print "fun3"
        return f
    
    def chained(*dec_funs):
        def _inner_chain(f):
            for dec in reversed(dec_funs):
                f = dec(f)
            return f
    
       return _inner_chain
    
    @fun1
    @fun2
    @fun3
    def do_stuff():
        pass
    
    @chained(fun1, fun2, fun3)
    def do_stuff2():
        pass
    
    all_funs = chained(fun1, fun2, fun3)
    
    @all_funs
    def do_stuff3():
        pass
    

    【讨论】:

      【解决方案3】:
      def all_funs(f):
          return fun1(fun2(fun3(f)))
      

      【讨论】:

        猜你喜欢
        • 2019-05-13
        • 2011-09-03
        • 1970-01-01
        • 2021-06-04
        • 1970-01-01
        • 2012-12-04
        • 2021-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多