如何在python中使用条件装饰符

2024-04-20 01:17:08 发布

您现在位置:Python中文网/ 问答频道 /正文

是否可以有条件地修饰函数。例如,我想用一个定时器函数(timeit)来修饰函数foo(),它只做True性能分析(参见下面的psuedo代码)。

if doing_performance_analysis:
  @timeit
  def foo():
    """
    do something, timeit function will return the time it takes
    """
    time.sleep(2)
else:
  def foo():
    time.sleep(2)  

Tags: 函数代码trueiffootimedefperformance
3条回答

怎么样:

def foo():
   ...

if doing_performance_analysis:
   foo = timeit(foo)

我想您甚至可以将其包装成一个decorator,该decorator将接受一个布尔标志和另一个decorator,并且仅当标志设置为True时才应用后者:

def cond_decorator(flag, dec):
   def decorate(fn):
      return dec(fn) if flag else fn
   return decorate

@cond_decorator(doing_performance_analysis, timeit)
def foo():
   ...

decorator是简单的可调用函数,可以返回替换函数、包装器或完全不同的东西。因此,您可以创建一个条件修饰符:

def conditional_decorator(dec, condition):
    def decorator(func):
        if not condition:
            # Return the function unchanged, not decorated.
            return func
        return dec(func)
    return decorator

现在您可以这样使用它:

@conditional_decorator(timeit, doing_performance_analysis)
def foo():
    time.sleep(2)  

decorator也可以是一个类:

class conditional_decorator(object):
    def __init__(self, dec, condition):
        self.decorator = dec
        self.condition = condition

    def __call__(self, func):
        if not self.condition:
            # Return the function unchanged, not decorated.
            return func
        return self.decorator(func)

这里,__call__方法扮演着与第一个示例中返回的decorator()嵌套函数相同的角色,这里的闭包deccondition参数作为参数存储在实例上,直到应用装饰符。

decorator只是应用于另一个函数的函数。您可以手动应用它:

def foo():
   # whatever
   time.sleep(2)

if doing_performance_analysis:
    foo = timeit(foo)

相关问题 更多 >