我试图为IRC库编写一个非常简单的接口,比如:
import simpleirc
connection = simpleirc.Connect('irc.freenode.net', 6667)
channel = connection.join('foo')
find_command = re.compile(r'google ([a-z]+)').findall
for msg in channel:
for t in find_command(msg):
channel.say("http://google.com/search?q=%s" % t)
从their example开始工作,我遇到了麻烦(代码有点长,所以我粘贴了here)。由于调用回调<IRCClient instance>.privmsg
时需要返回对channel.__next__
的调用,因此似乎没有一个干净的选项。在这里使用异常或线程似乎是错误的,有没有更简单的(阻塞?)使用twisted的方式会让这成为可能?在
一般来说,如果你试图以“阻塞”的方式使用Twisted,你会遇到很多困难,因为这既不是它的预期使用方式,也不是大多数人使用它的方式。在
随波逐流通常要容易得多,在这种情况下,这意味着接受回调。您的问题的回调式解决方案如下所示:
这不是绝对必要的(但我强烈建议您考虑尝试一下)。一种选择是
^{pr2}$inlineCallbacks
:请不要再注意}对象可以像这样可编辑:
addCallbacks
。在一个修饰的生成器函数中,它被yield
取代。如果您有一个使用不同API的Googler
版本,这可能会更接近您所要求的内容(上面的一个应该与Twisted中的IRCClient
一起工作——尽管我没有测试它)。对于Googler.join
返回某种类型的Channel
对象是完全可能的,并且该{这只是一个在已经存在的API之上实现这个API的问题。当然,
yield
表达式仍然存在,我不知道这会给您带来多大的不安。;)还可以远离回调,使异步操作所需的上下文切换完全不可见。这很糟糕,因为同样的原因,你家外面的人行道上到处都是看不见的捕熊器。然而,这是有可能的。使用类似于corotwine的东西,它本身基于CPython的第三方协同程序库,您可以让
Channel
的实现自己进行上下文切换,而不需要调用应用程序代码来进行切换。结果可能类似于:使用
Channel
的实现,可能类似于:这又取决于一个新的
Googler
方法,getNextMessage
,这是基于现有的IRCClient
回调的简单功能添加:要运行这个,您需要为
run
函数创建一个新的greenlet并切换到它,然后启动reactor。在当
run
开始第一个异步操作时,它将切换回reactor greenlet(在本例中,这是“main”greenlet,但实际上并不重要)来完成异步操作。完成后,corotwine将回调转换为greenlet开关返回到run
。因此run
被赋予了直接运行的错觉,就像一个“正常”的同步程序。但请记住,这只是一种错觉。在因此,可以尽量远离Twisted最常用的面向回调的样式。不过,这不一定是个好主意。在
相关问题 更多 >
编程相关推荐