我有一系列消费者发电机。从最后这些消费者中,我想在某个时间点返回结果。这有效:
class StopIterationWithResult(StopIteration):
def __init__(self, result):
super(StopIterationWithResult, self).__init__()
self.result = result
# for definition fo consumer decorator see http://www.python.org/dev/peps/pep-0342/
@consumer
def waitfor3():
while True:
value = (yield)
if value == 3:
raise StopIterationWithResult('Hello')
c = waitfor3()
for i in range(10):
try:
print 'calling', i
c.send(i)
except StopIterationWithResult as r:
print 'stopped', r.result
break
有更好的方法吗?例如,如果由于StopIteration
语句而引发return
,则可以访问生成器的返回值吗?
根据@alexis的要求,以下是管道示例:
class StopIterationWithResult(StopIteration):
def __init__(self, result):
super(StopIterationWithResult, self).__init__()
self.result = result
@consumer
def add1_filter(consumer):
while True:
value = (yield)
consumer.send(value+1)
@consumer
def waitfor3():
while True:
value = (yield)
print 'got', value
if value == 3:
raise StopIterationWithResult('Hello')
c = waitfor3()
f = add1_filter(c)
for i in range(10):
try:
print 'calling', i
f.send(i)
except StopIterationWithResult as r:
print 'stopped', r.result
break
这与@Martijn Pieters的答案相同 - 但过滤器有点难看,但是:
@consumer
def add1_filter(consumer):
result = None
while True:
value = (yield result)
result = consumer.send(value+1)
@consumer
def waitfor3():
while True:
value = (yield)
print 'got', value
if value == 3:
yield 'Hello'
break
c = waitfor3()
f = add1_filter(c)
r = None
for i in range(10):
try:
print 'calling', i
r = f.send(i)
except StopIteration:
print 'stopped', r
break
答案 0 :(得分:2)
收益率是双向的。在右手表达式中使用,它将接收并用作语句,它会产生表达式的结果。
只是产生结果值:
def waitfor3():
while True:
value = (yield)
if value == 3:
yield 'Hello'
break
c = waitfor3()
for i in range(10):
try:
print 'calling', i
result = c.send(i)
except StopIteration:
print 'stopped', result
break
答案 1 :(得分:0)
您不需要子类StopIteration
,您可以访问传递给它的构造函数的args
。见http://docs.python.org/2/library/exceptions.html#exceptions.BaseException:
@consumer
def add1_filter(consumer):
while True:
value = (yield)
consumer.send(value+1)
@consumer
def waitfor3():
while True:
value = (yield)
print 'got', value
if value == 3:
# This doesn't work:
# return 456 # SyntaxError: 'return' with argument inside generator
# But this does:
raise StopIteration(123)
c = waitfor3()
f = add1_filter(c)
for i in range(10):
try:
print 'calling', i
f.send(i)
except StopIteration as r:
print 'stopped (StopIteration)', r, type(r.args[0])
break