Python生成器协同程序

use*_*317 0 python generator coroutine

试图在python中了解更多的generator/send函数.我在链接中读到了一些内容:生成器发送功能的目的,帮助了很多.

但我想了解下面的代码.为什么有next(checker)必要?发送功能是否自动询问发电机中的下一个项目?我尝试next(checker)过在for循环之前,但是它的功能不同.我认为send函数将'attempt'作为x发送并产生是否x == password.我只是不明白为什么必须在循环中使用下一个(检查器).

def checkPassword(attempts, password):
    def check():
        while True:
            x = yield
            yield x == password

    checker = check()
    for i, attempt in enumerate(attempts):
        next(checker)
        if checker.send(attempt):
            return i + 1

    return -1
Run Code Online (Sandbox Code Playgroud)

上述功能基于以下问题:

"为了验证你的功能,你想在本地测试它.给定一个尝试列表和正确的密码,返回第一次正确尝试的从1开始的索引,如果没有则返回-1.

对于attempts = ["hello", "world", "I", "like", "coding"]password = "like",输出应为checkPassword(尝试,密码)= 4."

use*_*ica 5

发送功能是否自动询问发电机中的下一个项目?

是的,但是编写这个生成器的方式,一半的值来自于yield:

x = yield
Run Code Online (Sandbox Code Playgroud)

只是屈服None.next消费者的电话None.


可以用不同的方式编写生成器,以消除大多数next调用:

def checkPassword(attempts, password):
    def check():
        x = yield
        while True:
            x = yield x == password

    checker = check()
    next(checker)
    for i, attempt in enumerate(attempts):
        if checker.send(attempt):
            return i + 1

    return -1
Run Code Online (Sandbox Code Playgroud)

但是,生成器与其用户之间的yield/ send通信不能以a开头send,因为新的生成器在函数体的开头停止而不是在yield可以接收值的那个处停止.因此,在开始生成器将使用的值之前,必须始终存在next(或等效于a send(None))send.