발전기는-게으른 평가 이렇게 있습니다 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모듈 에서 추가 툴을 찾을 수 있습니다 . 그런 간단한 경우에 나는 단순히 이것에 의지하고 사소한 경우에만 자신의 발전기를 씁니다.
그러나 실제 코드가 더 복잡하여 적용 할 수 없을 수도 있지만 대안을 언급하지 않으면 완전한 답변이 아니라고 생각했습니다.