【问题标题】:Python3 decorating conditionally?Python3有条件地装饰?
【发布时间】:2011-04-15 23:18:58
【问题描述】:

是否可以根据条件装饰函数?

啊啦:

if she.weight() == duck.weight(): 
    @burn
def witch():
    pass

我只是想知道是否可以使用逻辑(何时调用witch?)来确定是否用@burn 装饰witch

如果不是,是否可以在装饰器中创建一个条件以达到相同的效果? (witch 被称为未装饰。)

【问题讨论】:

    标签: python conditional-statements decorator


    【解决方案1】:

    可以通过重新分配enable/disable decorators

    def unchanged(func):
        "This decorator doesn't add any behavior"
        return func
    
    def disabled(func):
        "This decorator disables the provided function, and does nothing"
        def empty_func(*args,**kargs):
            pass
        return empty_func
    
    # define this as equivalent to unchanged, for nice symmetry with disabled
    enabled = unchanged
    
    #
    # Sample use
    #
    
    GLOBAL_ENABLE_FLAG = True
    
    state = enabled if GLOBAL_ENABLE_FLAG else disabled
    @state
    def special_function_foo():
        print "function was enabled"
    

    【讨论】:

      【解决方案2】:

      你可以创建一个'有条件'的装饰器:

      >>> def conditionally(dec, cond):
          def resdec(f):
              if not cond:
                  return f
              return dec(f)
          return resdec
      

      用法示例如下:

      >>> def burn(f):
          def blah(*args, **kwargs):
              print 'hah'
              return f(*args, **kwargs)
          return blah
      
      >>> @conditionally(burn, True)
      def witch(): pass
      >>> witch()
      hah
      
      >>> @conditionally(burn, False)
      def witch(): pass
      >>> witch()
      

      【讨论】:

      • +1 我更喜欢这个而不是我的解决方案,因为它与装饰器主题保持一致,而且看起来很干净,imo。
      • 这是一个旧答案,但有谁知道如何使用这种模式将参数传递给条件包装的装饰器?
      【解决方案3】:

      装饰器只是重新定义函数的语法糖,例如:

      def wrapper(f):
          def inner(f, *args):
              return f(*args)
          return lambda *args: inner(f, *args)
      
      def foo():
          return 4
      foo = wrapper(foo)
      

      这意味着您可以在语法糖存在之前以旧方式进行:

      def foo():
          return 4
      if [some_condition]:
          foo = wrapper(foo)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-21
        • 2016-05-24
        • 2018-05-17
        • 2021-03-01
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多