根据条件应用不同的装饰器

Posted

技术标签:

【中文标题】根据条件应用不同的装饰器【英文标题】:Apply different decorators based on a condition 【发布时间】:2016-11-25 18:23:00 【问题描述】:

我正在使用单元测试和鼻子参数化,并希望根据条件将不同的装饰器应用于测试。

我有一个测试,我想跳过 unittest.skip 测试或根据传递给 args 的参数执行它 @parameterized.expand(args)

我想我需要另一个装饰器来将适当的装饰器应用于测试,但现在确定如何。

伪代码可能是这样的:

@validate_data(args)
    def test(args):
    ...

@validate_data(args) 是一个装饰器,如果 args ==None 或 @parameterized.expand(args)otherwise 则应用 unittest.skip

感谢任何 cmets/建议。

【问题讨论】:

【参考方案1】:

装饰器也可以作为函数调用。 @decorator 相当于 decorator(func)@decorator(args) 相当于 decorator(args)(func)。因此,您可以在装饰器中有条件地返回这些函数的值。下面是一个例子:

def parameterized_or_skip(args=None):
    if args:
        return parameterized.expand(args)
    return unittest.skip(reason='No args')

...

@parameterized_or_skip(args)
def my_testcase(self, a, b):
    pass

【讨论】:

因为parameterized.expand 做了讨厌的inspect.stack 魔法,你需要返回一个函数,该函数将从类的定义中调用,而不是在另一个函数中。我已经更新了你的答案,所以它应该可以工作。 @DavidWolever,啊!谢谢。我不知道那个函数做了什么:)

以上是关于根据条件应用不同的装饰器的主要内容,如果未能解决你的问题,请参考以下文章

python装饰器用户验。根据不同的帐号类,不同的登录方式

python之函数装饰器

python语言中的装饰器详解

使用两种不同的装饰器实现来装饰所有类方法的元类

PHP设计模式 - 装饰器模式

Decorator(装饰器模式)