inlineCallbacks函数内的回调
假设我有一个这样的函数:
def display(this, that):
print this, that
还有一个类:
class Runner(object):
def __init__(self, callback):
self.callback = callback
self.loop = twisted.internet.task.LoopingCall(repeat)
self.loop.start(0)
@defer.inlineCallbacks
def repeat(self):
this = yield do_this()
that = yield do_that()
if this and that:
# now I want to call the callback function
yield self.callback(this, that) # makes sense?
runner = Runner(display)
reactor.run()
基本上,我想做的是创建一个 Runner 类,这个类会执行一些特定的任务,每当它得到一个结果时,就会调用给定的回调函数。与其创建一个新的函数来做某件特定的事情,我想创建一个通用的类,只做一件事情。例如:
class TwitterReader(object):
def __init__(self, callback):
...
...
@defer.inlineCallbacks
def get_messages(self):
...
...
yield callback(messages)
class MessageFilter(object):
def __init__(self):
self.bad_messages = open('bad_messages.txt', 'w')
self.twitter = TwitterReader(self.message_received)
def message_received(messages):
for message in messages:
for bad_word in BAD_WORDS:
if bad_word in message:
self.bad_messages.write(message)
break
我刚接触 twisted,所以不太确定这样做是否正确。这样做可以吗?
谢谢
2 个回答
0
你只需要在调用 yield self.callback
的时候,如果它返回的是一个延迟对象(deferred),并且你想在退出 repeat
函数之前等到结果。那么在你的例子里,你的回调函数是一个普通的函数(实际上返回的是 None
),所以使用 yield 并没有什么好处。不过,使用 yield 返回非延迟的值也是可以的,所以这样做并不会有坏处。根据inlineCallbacks 的文档:
非延迟对象也可以被 yield,你的生成器会用同样的对象继续执行。这意味着 yield 的操作大致相当于 maybeDeferred。
如果你的回调函数 确实 返回了一个延迟对象(比如它也是一个带有 inlineCallbacks
装饰器的函数),那么使用 yield 会暂停 repeat
的执行,直到这个延迟对象完成。这在你的应用中可能是需要的,也可能不是。
2
你的问题是,repeat
里面的 callback
应该改成 self.callback
。
除此之外,你的例子应该可以照原样运行。