수익률 내부의 수익률은 무엇을합니까?
다음 코드를 고려하십시오.
def mygen():
yield (yield 1)
a = mygen()
print(next(a))
print(next(a))
결과는 다음과 같습니다.
1
None
통역사는 "외부"에서 정확히 무엇을합니까?
a
생성기 객체입니다. 처음 호출 next
할 때 본문은 첫 번째 yield
표현식 (즉, 평가할 첫 번째 표현식 : 내부 표현식) 까지 평가됩니다 . 즉, yield
가치 생산 1
에 대한 next
반환 할를 다음 블록 발전기에 다음 항목까지. 즉 두 번째 호출에 의해 생성되는 next
않는 하지 값을 전송 로 발전기. 결과적으로 첫 번째 (내부) yield
는로 평가됩니다 None
. 이 값은 yield
두 번째 호출의 반환 값이되는 외부 인수로 사용됩니다 next
. next
세 번째 로 전화 하면 StopIteration
예외 가 발생합니다.
첫 번째 표현식 의 반환 값을 변경 하려면 send
메서드 (대신 next
) 사용을 비교합니다 yield
.
>>> a = mygen()
>>> next(a)
1
>>> a.send(3) # instead of next(a)
3
>>> next(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
생성기를 작성하는보다 명시적인 방법은
def mygen():
x = yield 1
yield x
a = mygen()
print(a.send(None)) # outputs 1, from yield 1
print(a.send(5)) # makes yield 1 == 5, then gets 5 back from yield x
print(a.send(3)) # Raises StopIteration, as there's nothing after yield x
Python 2.5 이전에이 yield
명령문 은 호출자와 생성자 간의 단방향 통신을 제공했습니다. 에 대한 호출 next
은 다음 yield
문 까지 생성기를 실행하고 yield
키워드가 제공하는 값은의 반환 값으로 사용 next
됩니다. 생성기는 또한 yield
명령문 지점에서 일시 중지되어 다음 호출 next
이 재개 될 때까지 기다 립니다.
Python 2.5에서는 yield
문이 yield
표현식 으로 * 바뀌었고 생성기는 send
메서드를 얻었습니다 . send
매우처럼 작동 next
이 인수를 취할 수를 제외하고. (나머지의 경우는와 next(a)
동일 하다고 가정합니다 a.send(None)
.) 생성기는를 호출 한 후 실행을 시작 합니다 . send(None)
이 시점에서 첫 번째까지는 실행 yield
되어 이전과 같은 값을 반환합니다. 그러나 이제 식은에 전달 된 인수로 평가 되는 지점에서에 대한 다음 호출 까지 차단 됩니다 . 이제 생성기가 재개 될 때 값을 받을 수 있습니다 .send
yield
send
* 완전히 대체되지 않았습니다. kojiro의 대답은 yield
진술과 yield
표현 의 미묘한 차이에 대해 자세히 설명합니다 .
yield
두 가지 형태, 표현과 진술이 있습니다. 거의 동일하지만 statement
결과가 사용되지 않는 형태로 가장 자주 봅니다 .
def f():
yield a thing
그러나 표현식 형식 yield
에는 다음과 같은 값이 있습니다.
def f():
y = yield a thing
귀하의 질문에 두 가지 양식을 사용하고 있습니다.
def f():
yield ( # statement
yield 1 # expression
)
결과 생성기를 반복 할 때 먼저 내부 yield 표현식의 결과를 얻습니다.
>>> x=f()
>>> next(x)
1
이 시점에서 내부 표현식은 외부 문이 사용할 수있는 값을 생성했습니다.
>>> next(x)
>>> # None
이제 발전기를 다 소모했습니다.
>>> next(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
문 대 식에 대해 더 많이 이해하기 위해 다른 스택 오버플로 질문에 대한 좋은 답변이 있습니다. Python에서 식과 문의 차이점은 무엇입니까?
>>> def mygen():
... yield (yield 1)
...
>>> a = mygen()
>>>
>>> a.send(None)
1
>>> a.send(5)
5
>>> a.send(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
>>>
>>>
>>> def mygen():
... yield 1
...
>>> def mygen2():
... yield (yield 1)
...
>>> def mygen3():
... yield (yield (yield 1))
...
>>> a = mygen()
>>> a2 = mygen2()
>>> a3 = mygen3()
>>>
>>> a.send(None)
1
>>> a.send(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> a2.send(None)
1
>>> a2.send(0)
0
>>> a2.send(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> a3.send(None)
1
>>> a3.send(0)
0
>>> a3.send(1)
1
>>> a3.send(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
다른 모든 수익은 단순히 값이 전달되기를 기다립니다. 생성기는 데이터를 제공 할뿐만 아니라 데이터도받습니다.
>>> def mygen():
... print('Wait for first input')
... x = yield # this is what we get from send
... print(x, 'is received')
...
>>> a = mygen()
>>> a.send(None)
Wait for first input
>>> a.send('bla')
bla is received
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
yield
계속하면 다음 값을 얻고 다음 값을주는 데 사용되지 않으면 다음 값을받는 데 사용됩니다.
>>> def mygen():
... print('Wait for first input')
... x = yield # this is what we get from send
... yield x*2 # this is what we give
...
>>> a = mygen()
>>> a.send(None)
Wait for first input
>>> a.send(5)
10
>>>
모든 발전기는 소진 될 때까지 요소를 배출합니다.
아래와 같은 2 단계 중첩 예제에서 첫 번째 next
는 가장 안쪽의 yield에서 1 인 요소를 제공하고, 다음은 반환 None
할 요소가 없기 때문에를 반환 next
합니다. 다시 호출 하면 반환됩니다.StopIteration
def mygen():
yield (yield 1)
a = mygen()
print(next(a))
print(next(a))
print(next(a))
You can expand this case to include more nested yields, and you will see that after n
next
are called, StopIteration
expection is thrown, below is an example with 5 nested yields
def mygen():
yield ( yield ( yield ( yield (yield 1))))
a = mygen()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
Note that this answer is just based on my observation, and might not be technically correct in the nitty-gritties, all updates and suggestions are welcome
ReferenceURL : https://stackoverflow.com/questions/55922302/what-does-a-yield-inside-a-yield-do
'programing tip' 카테고리의 다른 글
Bash의 Shellshock 취약성 뒤에있는 동작이 문서화되어 있습니까? 아니면 의도적입니까? (0) | 2020.12.31 |
---|---|
“C : \ Microsoft.Cpp.Default.props”를 찾을 수 없습니다. (0) | 2020.12.31 |
Hive는 HBase와 어떻게 다릅니 까? (0) | 2020.12.31 |
Log4Net Wrapper 클래스는 어떻게 생겼습니까? (0) | 2020.12.31 |
docker-compose 동일한 이미지에 대해 여러 인스턴스 생성 (0) | 2020.12.30 |