2012-06-09 14 views
5

Biliyorum, basit bir şey eksik olmalıyım, ama göremiyorum.Jeneratör İfadesi vs verim: Neden 'next()' çalışmıyor?

Böyle bir jeneratör ifadesini varsa:

>>> serializer=(sn for sn in xrange(0,sys.maxint)) 

kolayca üretebilirsiniz, Bu gibi ayrı ayrı tamsayılar:

>>> serializer.next() 
0 
>>> serializer.next() 
1 
>>> serializer.next() 
2 

Böyle bir jeneratör yazarsanız:

>>> def ser(): 
... for sn in xrange(0,100000): 
...  yield sn 

Bueno değildir:

>>> ser().next() 
0 
>>> ser().next() 
0 
>>> ser().next() 
0 

??? Neyi kaçırıyorum ???

cevap

19

ser() jeneratör oluşturur. Yani, her bir kez ser() numaralı telefonu aradığınızda, size yeni bir jeneratör örneği gönderiyor. Sadece ifade gibi kullanabilirsiniz gerekir: bu bu şekilde işi olmasaydı

serializer = ser() 
serializer.next() 

, düşünün, sen sadece bir kere ser() işlevini kullanabilir ve bunu sıfırlamak asla. Ayrıca, max işlevini kabul etmek için ser işlevini değiştirebilir ve programınızı daha esnek hale getirebilirsiniz. İkinci örnekte

def ser(n=sys.maxint): 
    for sn in xrange(0, n): 
     yield sn 
+1

Thx! Basit olması gerektiğini biliyordum ... – dawg

+2

sorun değil. kesinlikle belirgin değildir, çünkü bunu yapan diğer ana işlevler (dekoratörler) içlerinde açık bir 'dönüş sarıcısı' bulundurmaktadırlar, ki bu sanırım "verim" ifadesiyle örtülü/büyülü bir şekilde yaratılmıştır. –

4
ser() 

bir yeni jeneratör her zaman başlatır.

böyle bir şey yapmak düzeltmek için:

s = ser() 
next(s) # next is preferred over .next which is why .next has been removed in Py3 
next(s) 
5

taze bir jeneratör ile başlayan yeni bir örneğini oluşturmaya devam ediyoruz.

g = ser() 
g.next() 
g.next() 

Jeneratörü bir kez oluşturun ve yeniden kullanın.