2012-12-18 2 views
1

저는 소비자 생성기의 파이프 라인을 가지고 있습니다. 이 소비자들 중 마지막 순간부터 어느 시점에서 결과를보고 싶습니다. 작동 방식 :소비자 생성기에서 단일 값 반환

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 

더 좋은 방법이 있습니까? 예를 들어, return 문 때문에 StopIteration이 발생하면 반환 값을 액세스 할 수 있습니까?

은 @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 피에 터스에 의해 대답과 동일합니다 -하게 필터 좀 더 추한하지만 :

@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 
+3

가 이해가 안 3' 후 정기적'StopIteration' 인상 : http://docs.python.org/2/library/exceptions.html#exceptions.BaseException 참조하십시오. – kreativitea

+0

예를 들어 파이프 라인을 사용할 수 있습니까? 개선 할 것이없는 개선을 제안하는 것은 어렵습니다. – alexis

답변

2

수익은 양방향으로 진행됩니다. 오른쪽 표현식에 사용되면 표현식의 결과를 산출하여이를 사용합니다. 당신은 args 당신은 그것의 생성자에 전달 액세스 할 수 있습니다, 당신은 StopIteration를 서브 클래 싱 할 필요가 없습니다

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 
+0

필터의 수정이 필요하다는 것을 깨닫고 응답에 동의하지 않습니다. 더 나은 대답이 있기를 희망합니다. – Sebastian

+0

그리고 실제로 필요한 것보다 하나 더 많은 가치를 제공하지 않으면 작동하지 않습니다. (범위 (10) 대신 범위 (4)로 시도하십시오) 또는 "호출 4"도 인쇄하는 것을 확인하십시오. – Sebastian

0

:

그냥 그 결과 값을 얻을 수 있습니다. = 그냥 값`후 마지막 객체를 생성하지 않는 이유

@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