2011-08-06 5 views
7

मैं एक फ्लास्क प्रोजेक्ट पर काम कर रहा था, एपीआई रैपर से कुछ डेटा प्राप्त कर रहा था। रैपर ने जनरेटर ऑब्जेक्ट वापस कर दिया, इसलिए मैं print मानों (for obj in gen_object: print obj) को फ्लास्क के render_template() पर पास करने से पहले मानता हूं।क्या पाइथन जनरेटर ऑब्जेक्ट्स ट्रैवर्स होने के बाद "अनुपयोगी" बन जाते हैं?

ऑब्जेक्ट्स में print जबकि पृष्ठ का अनुरोध करते समय, पृष्ठ खाली है। लेकिन for लूप को हटाकर पृष्ठ जनरेटर ऑब्जेक्ट की सामग्री प्रस्तुत करता है।

@app.route('/') 
def front_page(): 
    top_stories = r.get_front_page(limit=10) 
    # this for loop prevents the template from rendering the stories 
    for s in top_stories: 
     print s 
    return render_template('template.html', stories=top_stories) 

उत्तर

9

हां, जेनरेटर एक बार उपभोग करने के लिए सलाह देते हैं। हर बार जब हम जनरेटर को पुन: सक्रिय करते हैं तो हम इसे एक और मूल्य देने के लिए कहते हैं, और यदि स्टॉपइटरेशन अपवाद को फेंकने के लिए कोई और मूल्य नहीं है जो पुनरावृत्ति को रोक देगा। जनरेटर को यह जानने का कोई तरीका नहीं है कि हम उसे क्लोन किए बिना फिर से दोहराना चाहते हैं।

top_stories = list(top_stories) 

इस तरह आप एक से अधिक बार top_stories पुनरावृति कर सकते हैं:

जब तक रिकॉर्ड स्मृति में आराम से फिट कर सकते हैं, मैं बजाय एक सूची का प्रयोग करेंगे।

एक इटरेटर की प्रतिलिपि बनाने के लिए itertools.tee नामक एक फ़ंक्शन है जो आपकी मदद भी कर सकता है लेकिन यह कभी-कभी सूची का उपयोग करने से धीमा होता है। संदर्भ: http://docs.python.org/library/itertools.html?highlight=itertools.tee#itertools.tee

+0

यह किसी भी सूची का उपयोग करने से अधिक मेमोरी कुशल नहीं हो सकता है, इस पर निर्भर करता है कि टेड इटरेटर के अलग-अलग उपयोग अलग-अलग होते हैं। – hop