如何编写一个用@defer.inlineCallbacks修饰的方法,可能产生也可能不产生?

时间:2013-04-18 17:38:42

标签: python twisted

我的方法是以下形式:

@defer.inlineCallbacks
def myAsyncMethod():
    if someCondition:
        yield anotherAsyncMethod()

问题是,如果someCondition不是True,那么就不会产生任何收益,这实际上变成了同步函数。装饰器然后导致这是一个错误。

现在,我正在做yield 1。这是正确的做法吗? 我当然可以这样做:

d = Deferred()
d.callback(0)
yield d

但我不知道那是怎样的

编辑:我的意思是,如果我尝试yield myAsyncMethod(),那么它会产生异常。我不想要处理异常。避免它的一种方法是在myAsyncMethod()的末尾产生一些东西,但是还有另一种不这样做的方法。这里的常见做法是什么?

1 个答案:

答案 0 :(得分:2)

前提是不正确的。考虑:

>>> def foo():
...     if False:
...             yield
... 
>>> foo()
<generator object foo at 0x7f579cc4ccd0>
>>> 

这里,从不评估yield语句。但这并不会阻止foo返回生成器。

这意味着您可以使用inlineCallbacks来装饰这样的函数而没有任何问题。

>>> @inlineCallbacks
... def foo():
...     if False:
...             yield
... 
>>> foo()
<Deferred at 0x7f08328e3ef0  current result: None>
>>> 

由于生成器没有元素,因此您获得的结果是Deferred已经有None,正如您在此处所见。

此外,这意味着你可以调用这样一个函数并从另一个inlineCallbacks - 装饰函数中产生它而没有问题:

>>> @inlineCallbacks
... def bar():
...     print "Foo result is:", (yield foo())
... 
>>> bar()
Foo result is: None
<Deferred at 0x7f08328e3ef0  current result: None>
>>> 

您在此处看到bar已执行,产生调用foo的结果,打印出Deferred的结果,然后使用自己的Deferred完成(其中也已经有None结果。