4

我正在制作一个 Python irc 机器人。出于某种原因,我的 join() 方法中的 yield 语句使它完全跳过了该方法,但是如果我用 return 替换它,它就可以正常工作。但是,每次不成功的加入尝试都需要产生一个错误。

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

unsuccessful = bot.join(channels)

我将能够做到:

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

加入方法看起来像这样

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)

如果我用“return response”切换“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

它从消息生成器接收消息。这些命令是调用者正在寻找的服务器命令,当找到终止符时,终止符会从生成器中退出。这有点像协程。

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

4

1 回答 1

5

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

这样,您的代码将一直运行:

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

Python 2 文档中的生成器

不过,我不确定发电机是否适合您。当您遇到第一个错误时,您最好立即返回response,或者如果您想遍历所有通道,请将每个错误响应附加到错误列表并在完成后返回该列表。

于 2013-10-16T21:02:59.590 回答