Python 协程给出未知的 None 产量
Python coroutines gives unknown None on yield
我正在尝试根据用户输入构建一些数学运算的管道,并尝试打印此运算的累积结果。
例如,输入将是一个操作列表,然后是数字输入的数量,然后是这样的数字:
[square, accumulate]
3
1
2
3
这应该return类似于:
1
5
14
首先将 1 打印为 1*1,然后将 1 与 2*2 的结果相加得到 5,然后将其与 3*3 相加得到 14。
但是我的方法有问题,第二个数字输入总是变成 None 值,我不知道为什么。
我卡住了:
1
None
10
有什么想法吗?这是我的代码:
import math
import os
import random
import re
import sys
def printer():
while True:
x = yield
print(x)
def co_generator(n):
for _ in range(n):
x = int(input())
yield x
def get_root():
while True:
number = (yield)
yield math.floor(math.sqrt(number))
def get_square():
number = 0
while True:
number = (yield)
yield number**2
def accumulator():
acum = 0
while True:
acum += (yield)
yield acum
def operations_pipeline(numbers, operations, print_acum):
for num in numbers:
for i, w in enumerate(operations):
num = w.send(num)
print_acum.send(num)
for operation in operations:
operation.close()
print_acum.close()
if __name__ == '__main__':
order = input().strip()
n = int(input())
numbers = co_generator(n)
print_acum = printer()
next(print_acum)
root = get_root()
next(root)
accumulate = accumulator()
next(accumulate)
square = get_square()
next(square)
operations_pipeline(numbers, eval(order), print_acum)
我认为您需要在此处的 operations_pipeline
代码中添加对 next
的调用:
def operations_pipeline(numbers, operations, print_acum):
for num in numbers:
for i, w in enumerate(operations):
num = w.send(num)
next(w) # <<<--- this
如果没有它,我不相信它会第二次回到 get_square
,假设您的第一个输入是 [square, accumulate]
。
您正在编写您的代码,就好像 (yield)
接收一个值并且 yield whatever
发送一个值。它不是这样工作的。 所有 yield
都发送一个值并接收一个值。
当生成器执行 yield
时,它分两个阶段进行。首先,yield
的参数变为当前 next
或 send
调用的 return 值,生成器暂停执行。如果没有参数,则使用 None
。这就是您的 None
的来源
其次,当另一个 next
或 send
被执行时,生成器取消挂起,并且 send
参数(或 None
如果使用 next
) 成为 yield
表达式的值。
您正在尝试使用一个 yield
来接收 send
参数,并使用另一个来设置 send
的 return 值。您需要使用单个 yield
来设置 send
return 值并接收下一个 send
的参数。例如,
def get_square():
number = 0
while True:
number = yield number**2
或者,如果您想在生成器端使用单独的 yield
发送和接收值,则需要使用单独的 send
(或 next
)调用在另一端接收和发送值,并忽略 None
s。例如,
w.send(num)
num = next(w)
而不是 num = w.send(num)
,所以 operations_pipeline
看起来像
def operations_pipeline(numbers, operations, print_acum):
for num in numbers:
for w in operations:
w.send(num)
num = next(w)
print_acum.send(num)
for operation in operations:
operation.close()
print_acum.close()
def rooter():
number=0
while True:
number= yield math.floor(math.sqrt(number))
def squarer():
number=0
while True:
number= yield number**2
yield will give none try this way
def accumulator():
number=0
while True:
number+= yield number
我正在尝试根据用户输入构建一些数学运算的管道,并尝试打印此运算的累积结果。 例如,输入将是一个操作列表,然后是数字输入的数量,然后是这样的数字:
[square, accumulate]
3
1
2
3
这应该return类似于:
1
5
14
首先将 1 打印为 1*1,然后将 1 与 2*2 的结果相加得到 5,然后将其与 3*3 相加得到 14。 但是我的方法有问题,第二个数字输入总是变成 None 值,我不知道为什么。 我卡住了:
1
None
10
有什么想法吗?这是我的代码:
import math
import os
import random
import re
import sys
def printer():
while True:
x = yield
print(x)
def co_generator(n):
for _ in range(n):
x = int(input())
yield x
def get_root():
while True:
number = (yield)
yield math.floor(math.sqrt(number))
def get_square():
number = 0
while True:
number = (yield)
yield number**2
def accumulator():
acum = 0
while True:
acum += (yield)
yield acum
def operations_pipeline(numbers, operations, print_acum):
for num in numbers:
for i, w in enumerate(operations):
num = w.send(num)
print_acum.send(num)
for operation in operations:
operation.close()
print_acum.close()
if __name__ == '__main__':
order = input().strip()
n = int(input())
numbers = co_generator(n)
print_acum = printer()
next(print_acum)
root = get_root()
next(root)
accumulate = accumulator()
next(accumulate)
square = get_square()
next(square)
operations_pipeline(numbers, eval(order), print_acum)
我认为您需要在此处的 operations_pipeline
代码中添加对 next
的调用:
def operations_pipeline(numbers, operations, print_acum):
for num in numbers:
for i, w in enumerate(operations):
num = w.send(num)
next(w) # <<<--- this
如果没有它,我不相信它会第二次回到 get_square
,假设您的第一个输入是 [square, accumulate]
。
您正在编写您的代码,就好像 (yield)
接收一个值并且 yield whatever
发送一个值。它不是这样工作的。 所有 yield
都发送一个值并接收一个值。
当生成器执行 yield
时,它分两个阶段进行。首先,yield
的参数变为当前 next
或 send
调用的 return 值,生成器暂停执行。如果没有参数,则使用 None
。这就是您的 None
的来源
其次,当另一个 next
或 send
被执行时,生成器取消挂起,并且 send
参数(或 None
如果使用 next
) 成为 yield
表达式的值。
您正在尝试使用一个 yield
来接收 send
参数,并使用另一个来设置 send
的 return 值。您需要使用单个 yield
来设置 send
return 值并接收下一个 send
的参数。例如,
def get_square():
number = 0
while True:
number = yield number**2
或者,如果您想在生成器端使用单独的 yield
发送和接收值,则需要使用单独的 send
(或 next
)调用在另一端接收和发送值,并忽略 None
s。例如,
w.send(num)
num = next(w)
而不是 num = w.send(num)
,所以 operations_pipeline
看起来像
def operations_pipeline(numbers, operations, print_acum):
for num in numbers:
for w in operations:
w.send(num)
num = next(w)
print_acum.send(num)
for operation in operations:
operation.close()
print_acum.close()
def rooter():
number=0
while True:
number= yield math.floor(math.sqrt(number))
def squarer():
number=0
while True:
number= yield number**2
yield will give none try this way
def accumulator():
number=0
while True:
number+= yield number