2013-11-14 10 views
6

नीचे इस कोड को सही काम करता है:गलत समझा अजगर उपज

def file_gen(f_name): 
    f = open(f_name) 
    for line in f: 
     yield line 

gen_line = file_gen("foo.html") 
gen_line.next() # '<!DOCTYPE>\n' 
gen_line.next() # '<html> \n' 
gen_line.next() # ... next line in file 

लेकिन इस समारोह StopIteration को जन्म देती है। मुझे समझ में नहीं आता क्यों?

def file_gen(f_name): 
    f = open(f_name) 
    line = f.readline() 
    yield line 

gen_line = file_gen('foo.html') 
gen_line.next() # '<!DOCTYPE>\n' 
gen_line.next() # StopIteration 
+5

आप क्या होने की उम्मीद करेंगे? – delnan

+3

दूसरा वास्तव में पाइथन में एक वाक्यविन्यास त्रुटि है (आप 'उपज' लाइन को इंडेंट नहीं कर सकते) – 6502

+0

@ 6502 क्षमा करें, मैंने –

उत्तर

4

आपके पास:

def file_gen(f_name): 
    f = open(f_name) 
    line = f.readline() 
    yield line 

सूचना line = f.readline() यह केवल फ़ाइल में से 1 लाइन पढ़ता है।

की तुलना करें:

def g(x): 
    li=range(x) 
    yield li.pop() 

print list(g(10)) 
# [9] 
इस के साथ

:

def g(x): 
    li=range(x) 
    while li: 
     yield li.pop() 

print list(g(10)) 
# [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 

yield केवल एक विशेष वस्तु या अभिव्यक्ति के साथ एक बार कहा जा सकता है। रिसीवर द्वारा इसका उपयोग करने के बाद इसे पुन: उत्पन्न किया जाना चाहिए। इसलिए आपको फ़ाइल की प्रत्येक पंक्ति को पढ़ने के चारों ओर एक लूप की आवश्यकता है।

आप अपने दूसरे इस तरह से (कम पठनीय) फार्म का उपयोग कर सकते हैं:

def file_gen(f_name): 
    f = open(f_name) 
    while True: 
     line = f.readline() 
     if not line: 
      break 
     yield line 

आप आइटम उपज के लिए बनाने के लिए एक पाश की जरूरत है। आपके पहले मामले में, for line in f: yield line एक लूप है।

मैं अपने कार्य इस तरह से फिर से लिखने होगा:

def file_gen(f_name): 
    with open(f_name) as f: 
     for line in f: 
      yield line 
+0

thx, लेकिन मुझे नहीं पता कि मेरे रूप में क्या गलत है? –

+1

@ एएम सुल्तानोव: क्योंकि 'line = f.readline() 'केवल 1 पंक्ति पढ़ता है। आपको उस लूप के किसी रूप में लपेटने की ज़रूरत है - या तो लूप – dawg

+0

@ डारविग थैक्स के लिए एक और अधिक पठनीय 'के' लूप 'की आवश्यकता है, मुझे एहसास हुआ) –

1

नहीं

line = f.readline() 

केवल आप एक पंक्ति उपज के लिए देना पड़ता है? इसलिए यात्रा के बाद बंद हो जाता है ...

+0

को सही किया है, लेकिन यदि इस फ़ॉर्म का उपयोग करें: file = open (' foo.html ') file.readline() file.readline() ... यह दूसरी पंक्ति –

+0

पर नहीं रुकता है जब मैं कोशिश करता हूं कि यह मुझे पहले की बजाय दूसरी पंक्ति देता है, तो मैं अगले अगली() कॉल पर पुनरावृत्ति रोकता हूं, जैसा कि मैं उम्मीद करता हूं। किसी भी तरह, ऐसा लगता है कि आपको अपने मुद्दे के नीचे जाना है ... – gonkan

2

आप क्योंकि आप केवल एक परिणाम सामने आए गए दूसरे अगले() पर StopIteration मिलता है। क्या आप इसके बजाय ऐसा करने का मतलब था?

def file_gen(f_name): 
    f = open(f_name) 
    lines = f.readlines() 
    for line in lines: 
     yield line 
संबंधित मुद्दे