발전기는-게으른 평가 이렇게 있습니다 return
또는 yield
예외가 발생하는 경우 당신은 당신의 코드를 디버깅 할 때 다르게 행동이나됩니다.
와 return
당신에 발생하는 예외 generator
에 대해 아무것도 알 수 없습니다 generate_all
때 때문입니다, generator
정말 실행 이미 남아있는 generate_all
기능을. 함께 yield
거기가있을 것이다 generate_all
역 추적에.
def generator(some_list):
for i in some_list:
raise Exception('exception happened :-)')
yield i
def generate_all():
some_list = [1,2,3]
return generator(some_list)
for item in generate_all():
...
Exception Traceback (most recent call last)
<ipython-input-3-b19085eab3e1> in <module>
8 return generator(some_list)
9
---> 10 for item in generate_all():
11 ...
<ipython-input-3-b19085eab3e1> in generator(some_list)
1 def generator(some_list):
2 for i in some_list:
----> 3 raise Exception('exception happened :-)')
4 yield i
5
Exception: exception happened :-)
그리고 그것을 사용한다면 yield from
:
def generate_all():
some_list = [1,2,3]
yield from generator(some_list)
for item in generate_all():
...
Exception Traceback (most recent call last)
<ipython-input-4-be322887df35> in <module>
8 yield from generator(some_list)
9
---> 10 for item in generate_all():
11 ...
<ipython-input-4-be322887df35> in generate_all()
6 def generate_all():
7 some_list = [1,2,3]
----> 8 yield from generator(some_list)
9
10 for item in generate_all():
<ipython-input-4-be322887df35> in generator(some_list)
1 def generator(some_list):
2 for i in some_list:
----> 3 raise Exception('exception happened :-)')
4 yield i
5
Exception: exception happened :-)
그러나 이는 성능 저하를 초래합니다. 추가 생성기 레이어에는 약간의 오버 헤드가 있습니다. 따라서 return
일반적으로 yield from ...
(또는 for item in ...: yield item
) 보다 약간 빠릅니다 . 대부분의 경우 생성기에서 수행하는 작업이 일반적으로 런타임을 지배하므로 추가 계층이 눈에 띄지 않기 때문에 이것은 중요하지 않습니다.
그러나 yield
몇 가지 추가 장점이 있습니다. 단일 iterable로 제한되지 않고 추가 항목을 쉽게 생성 할 수도 있습니다.
def generator(some_list):
for i in some_list:
yield i
def generate_all():
some_list = [1,2,3]
yield 'start'
yield from generator(some_list)
yield 'end'
for item in generate_all():
print(item)
start
1
2
3
end
귀하의 경우 작업이 매우 간단하고이를 위해 여러 함수를 작성해야하는지도 모르겠습니다 map
. 대신 내장 또는 생성기 표현식을 대신 사용할 수 있습니다 .
map(do_something, get_the_list()) # map
(do_something(i) for i in get_the_list()) # generator expression
둘 다 동일해야합니다 (예외가 발생할 때 약간의 차이는 제외). 그리고 그들이 더 설명적인 이름이 필요하다면, 당신은 여전히 그것들을 하나의 기능으로 포장 할 수 있습니다.
iterables 빌트인에 대한 매우 일반적인 조작을 랩핑하는 여러 헬퍼가 있으며, 빌트인 itertools
모듈 에서 추가 툴을 찾을 수 있습니다 . 그런 간단한 경우에 나는 단순히 이것에 의지하고 사소한 경우에만 자신의 발전기를 씁니다.
그러나 실제 코드가 더 복잡하여 적용 할 수 없을 수도 있지만 대안을 언급하지 않으면 완전한 답변이 아니라고 생각했습니다.