我从中学到了stack_overflow_entry在 Python 中,装饰器按照它们在源代码中出现的顺序应用。
那么下面的代码片段应该如何表现?
@unittest.skip("Something no longer supported")
@skipIf(not something_feature_enabled, "Requires extra crunchy cookies to run")
def test_this():
....
第一个装饰器(如下所示)要求测试运行程序完全跳过test_this()
@unittest.skip("Something no longer supported")
而第二个装饰器则要求测试运行器有条件地跳过运行 test_this()
。
@skipIf(not Something_feature_enabled,“需要额外的脆 cookies 才能运行”)
那么这是否意味着除非我们首先放置条件跳过装饰器,否则 test_this
根本不会运行?
另外,Python中有没有办法定义装饰器的依赖执行?例如
@skipIf("Something goes wrong")
@skipIf(not something_feature_enabled, "Requires extra crunchy cookies to run")
@log
@send_email
def test_this():
....
这个想法是,如果 @skipIf("Something goError")
为 ,则启用
。@log
和 @send_email
的执行正确
如果我遗漏了一些非常明显的东西,我深表歉意。
最佳答案
我认为您可能错过了一个关键点:装饰器只是一个传递函数并返回函数的函数。
所以,它们是相同的:
@log
def test_this():
pass
def test_this():
pass
test_this = log(test_this)
同样:
@skip("blah")
def test_this():
pass
def test_this():
pass
test_this = skip("blah")(test_this)
一旦你明白了这一点,你所有的问题就会变得非常简单。
首先,是的,skip(…)
被用来装饰 skipIf(…)(test)
,所以如果它跳过它所装饰的东西, test
永远不会被调用。
定义装饰器调用顺序的方法是按照您希望调用它们的顺序编写它们。
如果您想动态地执行此操作,则首先可以通过动态应用装饰器来实现。例如:
for deco in sorted_list_of_decorators:
test = deco(test)
Also, is there any way in Python to define dependent execution of decorators?
不,他们都被处决了。与您所要求的内容更相关的是,每个装饰器都应用于被装饰的函数,而不是装饰器。
但是您始终可以将装饰器传递给条件装饰器:
def decorate_if(cond, deco):
return deco if cond else lambda f: f
然后:
@skipIf("Something goes wrong")
@decorate_if(something_feature_enabled, log)
@decorate_if(something_feature_enabled, send_email)
def test_this():
pass
很简单吧?
现在,如果 something_feature_enabled
为 true,则将应用 log
和 send_email
装饰器;否则,将应用不以任何方式装饰函数并且仅返回原样的装饰器。
但是如果由于函数已经被装饰而无法传递装饰器怎么办?好吧,如果您定义每个装饰器来公开它所包装的函数,那么您始终可以解开它。如果您始终使用 functools.wraps(如果您没有理由不这样做,通常应该这样做 - 即使您有这样的原因,您也可以轻松地以这种方式进行模拟),则包装的函数是始终以 __wrapped__
形式提供。因此,您可以编写一个装饰器,有条件地轻松删除最外层的装饰:
def undecorate_if(cond):
def decorate(f):
return f.__unwrapped__ if cond else f
return decorate
再说一遍,如果您尝试动态地执行此操作,那么您可能会动态地进行装饰。因此,一个更简单的解决方案是在应用装饰器之前将它们从 decos
可迭代对象中删除,从而跳过您不需要的装饰器。
关于python - python 装饰器是否可以根据较早的装饰器结果执行或跳过?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26746899/