【问题标题】:Co-routine returns None for every alternate iteration协程每次交替迭代都返回 None
【发布时间】:2020-07-15 12:29:58
【问题描述】:

我有一段代码如下图:

#!/bin/python3

import math
import os
import random
import re
import sys
import logging


def consumer():
    while True:
        x = yield
        print(x)

def producer(n):
    for _ in range(n):
        x = int(input())
        yield x


def rooter():
    logging.info("Running the rooter")
    while True:
        value = (yield)
        yield math.sqrt(value)


def squarer():
    logging.info("Running the squarer")
    while True:
        value = (yield)
        print("from squarer: {}".format(value))
        yield value * value


def accumulator():
    logging.info("Running the accumulator.")
    running_total = 0
    while True:
        value = (yield)
        running_total += value
        yield running_total


def pipeline(prod, workers, cons):
    logging.info("workers: {}".format(workers))
    for num in prod:
        for i, w in enumerate(workers):
            num = w.send(num)
        cons.send(num)
    for worker in workers:
        worker.close()
    cons.close()

if __name__ == '__main__':
    order = input().strip()
    m = int(input())

    prod = producer(m)

    cons = consumer()
    next(cons)

    root = rooter()
    next(root)

    accumulate = accumulator()
    next(accumulate)

    square = squarer()
    next(square)

    pipeline(prod, eval(order), cons)

示例输入

[square, accumulate]
3  <- Number of inputs coming further

1  <- actual inputs
2
3

样本输出

*The output should be as below:*
1
5
14

但来到 1013 的平方和)实际上应该是 14123 的平方和)

所以基本上输入2 被遗漏了(它是输入行中的第二个)。 在进一步调试时,我发现每次交替迭代都是这种情况,而不仅仅是此处提供的输入。

我无法破译发生了什么。如果有任何帮助,协程 squarer 是在第二次迭代中返回 None 的那个。 如有任何帮助,我将不胜感激。

【问题讨论】:

  • 请提供一个关于您的问题的简明示例...这目前需要在运行时进行未知输入并呈现 pdb。
  • 请立即查看。 @Attie

标签: python-3.x yield coroutinescope


【解决方案1】:

我找到了解决办法。

是我们在pipeline函数中使用后初始化协程所以代码变成如下:我在asterix中标记了next(w)行供参考。

#!/bin/python3

import math
import os
import random
import re
import sys
import logging


def consumer():
    while True:
        x = yield
        print(x)

def producer(n):
    for _ in range(n):
        x = int(input())
        yield x


def rooter():
    logging.info("Running the rooter")
    while True:
        value = (yield)
        yield math.sqrt(value)


def squarer():
    logging.info("Running the squarer")
    while True:
        value = (yield)
        print("from squarer: {}".format(value))
        yield value * value


def accumulator():
    logging.info("Running the accumulator.")
    running_total = 0
    while True:
        value = (yield)
        running_total += value
        yield running_total


def pipeline(prod, workers, cons):
    logging.info("workers: {}".format(workers))
    for num in prod:
        for i, w in enumerate(workers):
            num = w.send(num)
            **next(w)**
        cons.send(num)
    for worker in workers:
        worker.close()
    cons.close()

if __name__ == '__main__':
    order = input().strip()
    m = int(input())

    prod = producer(m)

    cons = consumer()
    next(cons)

    root = rooter()
    next(root)

    accumulate = accumulator()
    next(accumulate)

    square = squarer()
    next(square)

    pipeline(prod, eval(order), cons)

正如PEP specification 中提到的,它表示生成器函数的yield 当通过正常的next 调用恢复时,始终为None。因此,当明确向yield 发送时,在这种情况下,它将准备好立即处理下一个输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多