2016-04-19 21 views
8

Bir jeneratör işlevini başlattığınızda, üzerinde next numaralı çağrıyı çağırana kadar hiçbir kod yürütmez.Python üreteci işlevinin ilk verimden hemen önce ilerlemesi

Bu, jeneratör işlevi bir çeşit başlatma kodu içeriyorsa, yinelenene kadar çalıştırılmayacağı anlamına gelir.

def generator(filename): 
    with open(filename) as f: 
     data = f.read() 

    while True: 
     yield data 

gen = generator('/tmp/some_file') 
# at this point, no generator code is executed 

# initialization code is executed only at the first iteration 
for x in gen: 
    pass 

dosya yoksa, istisna döngü de yükseltilecek:

Bu örneği ele alalım. Jeneratörün yinelenmesinden önce çalıştırılacak ilk yield'dan önceki kod gibi kodlarını beğenirim, böylece başlatma sırasında tüm özel durumlar jeneratör örneğinde yükseltilecektir.

Bunu yapmanın temiz pythonik bir yolu var mı?

+0

@ TadhgMcDonald-Jensen: Vay, kimse "ayrı başlatma işlevi" çözümünü üç yıl boyunca yayınlamadı. Bu soruya verilen cevap, işe yarıyor, ancak sizi, jeneratörlerinizin sizi kurtarmayı amaçladığı bir devlet makinesi olarak yineleyicinizi yazmanın tüm can sıkıcılarıyla uğraşmaya zorlar. – user2357112

+0

@ user2357112 daha sonra kabul edilen çözümü kullanmazsınız, ancak WGH'nin jeneratörün başlatılmasından sonra bir kodun çalışmasını isteyip istemediğini sorarsınız. –

+0

şahsen, [ilkel fonksiyon çözümünü] (http://stackoverflow.com/a/5725046/5827215) bu soruyu ilk bulduğumda aradığımı buldum. işlev yineleyici ile çağırılmak yerine. –

cevap

5

Wrap jeneratör etrafında düzenli bir fonksiyonu ve orada başlatma koyun: (. Bu durumda, genel olarak itertools.repeat ile iç jeneratörü değiştirin ama olamazdı)

def file_contents_repeated(filename): 
    with open(filename) as f: 
     data = f.read() 
    return _gen(data) 

def _gen(data): 
    while True: 
     yield data 

2

işlevi sarıcı çözümü iyi çalışıyor. Tüm kodu aynı işlevde tutmak istiyorsanız, bir kapatma oluşturabilirsiniz.

def generator(filename): 
    with open(filename) as f: 
     data = f.read() 

    def _generator(): 
     while True: 
      yield data 

    return _generator() 
İlgili konular