Для моего случая использования я использовал модифицированную версию @ ncoghlan answer , но обернутую в заводскую функцию для украшения генерирующей функции:
import collections, functools, itertools
def primed_generator(generating_function):
@functools.wraps(generating_function)
def get_first_right_away_wrapper(*args,**kw):
"call the generator function, prime before returning"
gen = generating_function(*args,**kw)
assert isinstance(gen,collections.Iterator)
first_value = next(gen)
return itertools.chain((first_value,),gen)
return get_first_right_away_wrapper
Затем просто украсим функцию:
@primed_generator
def mygenerator():
next_value = compute_first_value() # Costly operation
while next_value != terminating_value:
yield next_value
next_value = compute_next_value()
, и первое значение будет вычислено немедленно, а результат будет прозрачным.