2017-05-16 4 views
0

파이썬에서 생성자에 여러 값을 전달할 수 있는지 궁금합니다.파이썬에서 생성자에 여러 값 전달하기

>>> it = counter(10) 
>>> next(it) 
0 
>>> next(it) 
1 
>>> it.send(8) 
8 
>>> next(it) 
9 
>>> next(it) 
Traceback (most recent call last): 
    File "t.py", line 15, in <module> 
    it.next() 
StopIteration 

질문은 두 가지이다 :

def counter(maximum): 
    i = 0 
    while i < maximum: 
     val = (yield i) 
     # If value provided, change counter 
     if val is not None: 
      i = val 
     else: 
      i += 1 

상기 기능을 실행 : I 하나를 전달하는 예를 알았다.

먼저 counter 함수가 변수 val에 대해 어떻게 알 수 있습니까? 그것은 어디에도 정의되거나 전달되지 않는 것 같습니다. 발전기에 가치를 전달하고자 할 때이 이름을 사용하도록 강요하는 협약이 있습니까?

두 번째 질문은 어떻게 여러 값을 생성기에 전달할 수 있는가입니다. 단일 send() 통화로이 작업을 수행 할 수 있습니까? 아니면 여러 번 통화해야합니까?

답변

1

첫 번째 대답 : val은 완전히 임의의 이름입니다. 여기서 유효한 파이썬 식별자를 사용할 수 있습니다. 표현식의 값에 명시 적으로 바인딩하기 때문에 counter은 "알고"있습니다. 아무 것도 전송되지 않으면 None이되며 (일반 next(it) 호출) 또는 it.send()으로 전달 된 것이 모두 있습니다.

두 번째 : send()은 하나의 값을 취하지 만, tuple 또는 list (발전기가 올바르게 처리하는 한)을 통과시키지 못합니다.

편집 : 코멘트

에 다른 질문에 대답하면 발은 항상 루프의 마지막 반복을 제외하지 아무도 없어야하지 않을까요?

왜? yield <whatever>의 실행은 생성자에 대한 일반 반복과 generator.send(something)에 대한 명시 적 호출에 의해 트리거됩니다. 첫 번째 경우에 yield whatever "표현식"의 값 (기술적으로는 yield이 성명이지만 여기서는 표현식처럼 동작하는 값을 "생성"할 수 있기 때문에)은 None입니다. 두 번째 경우에는 .send()으로 전달 된 것이 전부입니다.

이것은 반복 횟수 나 내부 루프 (생성자에서 내부 루프를 가질 필요가없는 것)와는 아무런 관련이 없습니다.

>>> def gen(x): 
...  for i in xrange(x): 
...   print "before yield" 
...   wot = (yield x) 
...   print "after yield - wot is '%s'" % wot 
...   if wot is not None: 
...    x = wot 
...    print "x is now %s" % x 
... 
>>> g = gen(5) 
>>> next(g) 
before yield 
5 
>>> next(g) 
after yield - wot is 'None' 
before yield 
5 
>>> g.send(10) 
after yield - wot is '10' 
x is now 10 
before yield 
10 
>>> next(g) 
after yield - wot is 'None' 
before yield 
10 
:이다

는 발전기 정확히

는 그것은 yield 문에 그것의 실행을 일시 중단 수율을 발생에 "정지"를 선택하고 다음 반복 또는 .send() 통화를 다시 시작하지

실제로 조건부를 통과하여 내가 무엇을해야할지 결정하고 yield 한 다음 다른 next()가 호출 될 때까지 실행을 일시 중단합니다. 디?위의

대답 - 당신은 실제로 자신이 발견 한 수) 내가 볼

+0

. 루프의 마지막 반복을 제외하고 항상 'val'이 'None'이 아닌가? 즉, 생성기가 'yield'를 만나면 정확히 "동결"합니까? 실제로 조건부를 통과하여'i'가 무엇인지 결정하고 yield 한 다음 다른 next()가 실행될 때까지 실행을 일시 중단합니다. 호출 되었습니까? – MadPhysicist

+0

cf 수정 된 답변 –