"ईओएफ नहीं है" के लिए अजगर में सही समकक्ष क्या है


115

कुछ पाठ फ़ाइल को पढ़ने के लिए, C या पास्कल में, मैं हमेशा EOF तक डेटा पढ़ने के लिए निम्नलिखित स्निपेट का उपयोग करता हूं:

while not eof do begin
  readline(a);
  do_something;
end;

इस प्रकार, मुझे आश्चर्य है कि मैं पायथन में यह सरल और तेज़ कैसे कर सकता हूं?

जवाबों:


191

लाइनों को पढ़ने के लिए फाइल पर लूप करें:

with open('somefile') as openfileobject:
    for line in openfileobject:
        do_something()

EOF तक फ़ाइल ऑब्जेक्ट पुनरावृत्त और उपज लाइनें हैं। फ़ाइल ऑब्जेक्ट का उपयोग करने योग्य के रूप में उपयोग करने के लिए एक बफर का उपयोग करता है ताकि यह सुनिश्चित हो सके कि प्रदर्शन रीड्स।

आप स्टडिन के साथ भी ऐसा कर सकते हैं (उपयोग करने की आवश्यकता नहीं है raw_input():

import sys

for line in sys.stdin:
    do_something()

तस्वीर को पूरा करने के लिए, बाइनरी रीड्स के साथ किया जा सकता है:

from functools import partial

with open('somefile', 'rb') as openfileobject:
    for chunk in iter(partial(openfileobject.read, 1024), b''):
        do_something()

जहां chunkफ़ाइल से एक समय में 1024 बाइट के लिए ऊपर में शामिल होंगे, और यात्रा बंद हो जाता है जब openfileobject.read(1024)शुरू होता है खाली बाइट तार लौटने।


4
नोट: lineअंत में एक नया लाइन वर्ण होगा।
19_में बोस_जोसेफ

1
जेनेरिक बाइनरी फ़ाइलों के लिए पढ़ना लाइनें थोड़ा खतरनाक है, क्योंकि शायद आपके पास एक 6GiB लंबी रेखा है ...
LtWorf

@LtWorf: यही कारण है कि मैं दिखाता हूँ कि लाइनों के बजाय बंक फ़ाइलों को बाइनरी फ़ाइलों को कैसे पढ़ा जाए ।
मार्टिन पीटर्स

मैं stdinएक चल रही प्रक्रिया से पढ़ रहा हूं ... इसलिए जब तक मैं इस प्रक्रिया को नहीं मारता, तब तक यह ईओएफ नहीं है। लेकिन फिर मैं "अब तक का अंत" और मैं गतिरोध पर पहुंच गया। मैं इसका पता कैसे लगाऊं और गतिरोध नहीं? जैसे अगर कोई नई लाइनें नहीं हैं, तो फ़ाइलों को पढ़ना बंद करें (भले ही कोई ईओएफ नहीं है, जो मेरे मामले में कभी मौजूद नहीं होगा)।
चार्ली पार्कर

@CharlieParker: यदि आप गतिरोध पर पहुंच गए हैं, तो कुछ शायद बफर को फ्लश करना भूल रहा है। वास्तविक MCVE के बिना, इससे अधिक कुछ भी कहना मुश्किल है।
मार्टिन पीटर्स

61

आप पायथन में सी मुहावरे का अनुकरण कर सकते हैं।

max_sizeबाइट्स की संख्या तक एक बफर पढ़ने के लिए , आप यह कर सकते हैं:

with open(filename, 'rb') as f:
    while True:
        buf = f.read(max_size)
        if not buf:
            break
        process(buf)

या, लाइन द्वारा एक पाठ फ़ाइल लाइन:

# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
    while True:
        line = f.readline()
        if not line:
            break
        process(line)

पाइथन में कोई ईओएफ टेस्ट नहींwhile True / break है, इसके अलावा आपको निर्माण का उपयोग करने की आवश्यकता है , बाइट्स की कमी के अलावा एक रीड से लौटे।

सी में, आपके पास हो सकता है:

while ((ch != '\n') && (ch != EOF)) {
   // read the next ch and add to a buffer
   // ..
}

हालाँकि, आप पायथन में यह नहीं कर सकते:

 while (line = f.readline()):
     # syntax error

क्योंकि अभिव्यक्तियों में असाइनमेंट की अनुमति नहीं है पायथन में (हालांकि पायथन के हालिया संस्करण असाइनमेंट एक्सप्रेशन का उपयोग करके इसकी नकल कर सकते हैं, नीचे देखें)।

ऐसा करने के लिए निश्चित रूप से पायथन में अधिक मुहावरेदार है:

# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
    for line in f:
        process(line)

अद्यतन: पायथन 3.8 के बाद से आप असाइनमेंट एक्सप्रेशन का उपयोग कर सकते हैं :

 while line := f.readline():
     process(line)

@MartijnPieters: अब यह :-)
dawg

3
एक सी और पर्ल प्रोग्रामर के रूप में, आपकी बात कि अभिव्यक्ति में असाइनमेंट की अनुमति नहीं है, मेरे लिए महत्वपूर्ण था।
CODE-REaD

1
"जबकि ट्रू:" विधि भी उपयोगी है जब आपको प्रति चलन से अधिक एक इनपुट लाइन पर संचालित करने की आवश्यकता होती है, कुछ ऐसा जो मुहावरेदार पायथन को अनुमति नहीं देता है (जहां तक ​​मैं बता सकता हूं, वैसे भी)।
डोनाल्ड स्मिथ

यदि आप फ़ाइल पर अनुमान नहीं लगाते हैं तो आपको लाइनें नहीं पढ़नी चाहिए। एक बाइनरी फ़ाइल में बड़ी लाइनें हो सकती हैं ...
LtWorf

ऐसा लगता है कि गैर-मुहावरेदार readline()तरीके से एक फायदा है : आप ठीक-ठाक त्रुटि से निपटने, कैचिंग की तरह UnicodeDecodeErrorकर सकते हैं, जिसे आप मुहावरेदार forपुनरावृत्ति के साथ नहीं कर सकते ।
flow2k

17

एक फ़ाइल खोलने और उसे लाइन-बाय-लाइन पढ़ने के लिए पायथन मुहावरा है:

with open('filename') as f:
    for line in f:
        do_something(line)

फ़ाइल उपरोक्त कोड के अंत में स्वचालित रूप से बंद हो जाएगी ( withनिर्माण उस का ध्यान रखता है)।

अंत में, यह ध्यान देने योग्य है जो lineअनुगामी न्यूलाइन को संरक्षित करेगा। इसका उपयोग करके आसानी से हटाया जा सकता है:

line = line.rstrip()

1
+1, यह भी ओ पी है कि यह करने के लिए उनका कहना है नहीं बहुत समान रूप में एक ही for line in f.readlines(): ..., एक सामान्य सुझाव दिया समाधान।
jedwards

12

आप फ़ाइल के अंत तक लाइन को पढ़ने के लिए कोड स्निपेट के नीचे उपयोग कर सकते हैं

line = obj.readline()
while(line != ''):

    # Do Something

    line = obj.readline()

1
IMO, यह एक उत्तर है जो सबसे अच्छा दर्शाता है जो पूछा गया था।
gvrocha

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

11

जबकि "इसे अजगर तरीके से करने" के लिए ऊपर सुझाव दिए गए हैं, अगर कोई ईओएफ के आधार पर तर्क करना चाहता है, तो मुझे लगता है कि अपवाद हैंडलिंग का उपयोग करने का तरीका है -

try:
    line = raw_input()
    ... whatever needs to be done incase of no EOF ...
except EOFError:
    ... whatever needs to be done incase of EOF ...

उदाहरण:

$ echo test | python -c "while True: print raw_input()"
test
Traceback (most recent call last):
  File "<string>", line 1, in <module> 
EOFError: EOF when reading a line

या Ctrl-Zएक raw_input()प्रॉम्प्ट पर दबाएँ (Windows, Ctrl-ZLinux)


@TessellatingHeckler वह नहीं है जो दस्तावेज़ कहता है: "जब कोई भी डेटा पढ़े बिना एक अंतर्निहित फ़ाइल फ़ंक्शंस (इनपुट या रॉ_इनपुट ()) एक अंत-टू-फ़ाइल स्थिति (EOF) को हिट करता है।"
तदह मैकडॉनल्ड्स-जेनसेन

1
@ तद्ग्मकडोनल्ड-जेनसेन वेल हे, तो यह होगा। कितना अजीब। झूठे दावे को हटा दिया गया और अनुचित तरीके से हटा दिया गया।
TessellatingHeckler

1

आप निम्न कोड स्निपेट का उपयोग कर सकते हैं। readlines () एक बार में पूरी फ़ाइल में पढ़ती है और इसे लाइन से विभाजित करती है।

line = obj.readlines()

0

@ डॉग के शानदार जवाब के अलावा, वालरस ऑपरेटर (पायथन> = 3.8) का उपयोग करके समतुल्य समाधान:

with open(filename, 'rb') as f:
    while buf := f.read(max_size):
        process(buf)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.