收益率不起作用,但回报确实有效

时间:2013-10-16 20:46:37

标签: python irc

我正在制作一个Python irc bot。由于某种原因,我的join()方法中的yield语句使它完全跳过该方法,但如果我用返回替换它,它可以正常工作。但是,我需要为每次不成功的连接尝试产生错误。

我有一个bot的join方法,如果由于某种原因连接失败,则返回服务器错误命令代码响应。如果机器人成功加入,则为无。

unsuccessful = bot.join(channels)

我能做到:

if unsuccessful:
    for error in unsuccessful:
        print(error)

join方法如下所示

def join(self, channels):
    chan_errors = range(471, 480)  # See RFC for commands 471-479

    if isinstance(channels, str):
        channels = [channels,]

    for channel in channels:
        self.send('JOIN %s' % channel)
        for response in self.get_response('JOIN', chan_errors):  # Verify
            if response.command in chan_errors:
                channels.remove(channel)
                yield response
    self.channels.append(channels)

如果我用“返回响应”切换“yield response”,它将运行该方法。

get_response方法看起来像

def get_response(self, commands, terminators=None):
    for msg in self.msg_gen():
        self.handle(msg)
        if msg.command in commands:
            if terminators is None:
                return msg
            yield msg
        if msg.command in terminators:
            return msg

它从消息生成器接收消息。这些命令是调用者正在查找的服务器命令,当找到终结符时,终结符将从生成器中删除。它有点像协程。

有谁知道这里发生了什么?

1 个答案:

答案 0 :(得分:4)

通过在yield方法中添加join语句,您可以将其设为生成器。调用生成器方法只会创建一个生成器函数;你需要迭代它来获取数据。但是,由于生成器内的执行在每次命中yield语句时都会停止,因此如果您希望它完全运行,则需要耗尽其所有内容。

这样您的代码就会一直运行:

join_gen = bot.join(channels)
for error_msg in join_gen:
    print error_msg

Generators in the Python 2 docs

我不确定发电机对你来说是个不错的选择。当您遇到第一个错误时,可能会更好地返回response,或者如果您想要浏览所有通道,请将每个错误响应附加到错误列表,并在完成后返回该列表。

相关问题