2012-04-04 13 views
5

मैंने हमेशा सोचा था कि पाइथन में फ़ाइल की तरह इसे फिर से चलाना एक लूप में readline विधि को कॉल करने के बराबर होगा, लेकिन आज मुझे एक ऐसी स्थिति मिली जहां यह सच नहीं है। विशेष रूप से, मैं एक Popen 'घ प्रक्रिया p है जहांफ़ाइल-जैसी और रीडलाइन को कॉल करने के बीच अंतर

list(itertools.takewhile(lambda x: x != "\n", 
         p.stdout)) 

रुक जाता है (इनपुट के लिए शायद क्योंकि p प्रतीक्षा करता है, दोनों stdin और stdout मेरी अजगर की प्रक्रिया के लिए पाइप हैं) है, जबकि निम्न काम करता है:

list(itertools.takewhile(lambda x: x != "\n", 
         iter(p.stdout.readline, ""))) 

क्या कोई अंतर बता सकता है?

+0

साइड नोट: 'fiter() 'के बजाय आप' iter (f.readline, none)', या यहां तक ​​कि 'iter (f.readline," \ n ")' 'takewhile()' को प्रतिस्थापित करने के लिए उपयोग कर सकते हैं। –

+0

जो समस्या आप देख रहे हैं वह बफरिंग से संबंधित है: 'file.__ iter __()' file.readline() 'की तुलना में किसी भी तरह से अधिक आक्रामक बफरिंग करता है - यही कारण है कि आप उन्हें मिश्रण नहीं कर सकते हैं। विवरणों का शोध करने के लिए बहुत आलसी है और इस समय इसे एक जवाब में बदल दें ... –

+0

@ स्वेनमार्कक: आपका मतलब है 'इटर (एफ .readline, "")', लेकिन हाँ, धन्यवाद, मैं इसके बारे में भूल रहा हूं :) –

उत्तर

4

अंतर readline विधि बनाम पुनरावृत्ति के कार्यान्वयन में पूरी तरह से अंतर है। फ़ाइल पुनरावृत्ति ब्लॉक (8 किलोबाइट्स, डिफ़ॉल्ट रूप से) में पढ़ती है और फिर बफर को लाइनों में विभाजित करती है जैसे आप उनका उपभोग करते हैं। दूसरी ओर, readline विधि, एक से अधिक पंक्तियों को पढ़ने के लिए कभी भी देखभाल नहीं करती है, और इसका मतलब चरित्र द्वारा चरित्र पढ़ना है। ब्लॉक में पढ़ना अधिक कुशल है, लेकिन इसका मतलब है कि आप पाठ के बीच फ़ाइल पर अन्य परिचालनों को मिश्रित नहीं कर सकते हैं। उम्मीद यह है कि जब आप फ़ाइल पर पुनरावृत्ति कर रहे हैं, तो आपका इरादा अनुक्रमिक रूप से सभी पंक्तियों को पढ़ना है और आप इस पर अन्य परिचालन नहीं करेंगे। readline विधि उस धारणा को नहीं बना सकती है।

के रूप में स्वेन Marnach अपने प्रश्न का उसकी टिप्पणी में संकेत दिया है, तो आप उपयोग कर सकते हैं iter(f.readline, '') प्रदर्शन की कीमत पर ब्लॉकों में पढ़ने के बिना एक इटरेटर है कि फाइल से लाइनों पढ़ता प्राप्त होते हैं।

+0

क्या आप जानते हैं कि सीपीथॉन स्रोत कोड में मैं फ़ाइल इटरेटर के कार्यान्वयन को पा सकता हूं? –

+0

'ऑब्जेक्ट्स/fileobject.c' में। फ़ाइल ऑब्जेक्ट्स अपने स्वयं के इटरेटर हैं, इसलिए कोई अलग प्रकार नहीं है। 'file.readline'' file_readline' है, और पुनरावृत्ति 'file_iternext' के माध्यम से की जाती है। –