programing tip

수익률 내부의 수익률은 무엇을합니까?

itbloger 2020. 12. 31. 08:00
반응형

수익률 내부의 수익률은 무엇을합니까?


다음 코드를 고려하십시오.

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되어 이전과 같은 값을 반환합니다. 그러나 이제 식은에 전달 된 인수로 평가 되는 지점에서에 대한 다음 호출 까지 차단 됩니다 . 이제 생성기가 재개 될 때 값을 받을 수 있습니다 .sendyieldsend


* 완전히 대체되지 않았습니다. 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

반응형