मैं एक खुली फाइल पर दो बार रीड () क्यों नहीं कह सकता?


98

एक अभ्यास के लिए, जो मैं कर रहा हूं, मैं read()विधि का उपयोग करके किसी दिए गए फ़ाइल की सामग्री को दो बार पढ़ने की कोशिश कर रहा हूं । अजीब बात है, जब मैं इसे दूसरी बार कहता हूं, तो यह फ़ाइल सामग्री को स्ट्रिंग के रूप में वापस नहीं करता है?

यहाँ कोड है

f = f.open()

# get the year
match = re.search(r'Popularity in (\d+)', f.read())

if match:
  print match.group(1)

# get all the names
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f.read())

if matches:
  # matches is always None

निश्चित रूप से मुझे पता है कि यह सबसे कुशल या सबसे अच्छा तरीका नहीं है, यह यहाँ बात नहीं है। मुद्दा यह है कि मैं read()दो बार कॉल क्यों नहीं कर सकता ? क्या मुझे फ़ाइल हैंडल रीसेट करना है? या ऐसा करने के लिए फ़ाइल को फिर से खोलें / बंद करें?


2
आपको यह विचार कहां से मिला कि पढ़ने से फ़ाइल की स्थिति नहीं बदलेगी? आप किस संदर्भ या ट्यूटोरियल का उपयोग कर रहे हैं?
एस.लूट

मेरा मानना ​​है कि फ़ाइल को बंद करना और फिर से खोलना नीचे दिए गए awers के आधार पर काम करना चाहिए।
एंथनी

@ वंशावली: फाइल को बंद करना और फिर से खोलना हमेशा एक अच्छा विचार नहीं है क्योंकि इससे सिस्टम में अन्य प्रभाव (अस्थायी फाइलें, इंक्रॉन आदि) हो सकते हैं।
इग्नासियो वाज़केज़-अब्राम्स

3
मैं बस स्पष्ट रूप से बताना चाहता हूं: आपने दो बार रीड () कॉल किया था!

4
डब्ल्यू / आर / टी / एस.लॉट, और 5 साल से: यह वास्तव में अजगर प्रलेखन में होना चाहिए। यह स्पष्ट नहीं है कि किसी को यह मानना ​​चाहिए कि किसी फ़ाइल ऑब्जेक्ट को पढ़ने से किसी भी चीज की स्थिति बदल जाएगी, खासकर अगर किसी को अपरिवर्तनीय डेटा / कार्यात्मक-शैली प्रोग्रामिंग के साथ काम करने के लिए उपयोग किया जाता है ...
पॉल गाउडर

जवाबों:


156

कॉलिंग read()पूरी फ़ाइल के माध्यम से पढ़ता है और फ़ाइल के अंत में रीड कर्सर छोड़ देता है (पढ़ने के लिए अधिक कुछ नहीं)। आप इस्तेमाल कर सकते हैं आप एक समय में लाइनों की एक निश्चित संख्या को पढ़ने के लिए देख रहे हैं readline(), readlines()या पुनरावृति के साथ लाइनों के माध्यम से for line in handle:

सीधे आपके प्रश्न का उत्तर देने के लिए, एक बार एक फ़ाइल पढ़ ली गई है, read()तो आप seek(0)फ़ाइल की शुरुआत में रीड कर्सर को वापस करने के लिए उपयोग कर सकते हैं (डॉक्स यहां हैं )। यदि आप जानते हैं कि फ़ाइल बहुत बड़ी नहीं होने वाली है, तो आप read()आउटपुट को एक वैरिएबल में भी सहेज सकते हैं , इसे अपने खोज अभिव्यक्तियों में उपयोग कर सकते हैं।

Ps। आपके द्वारा किए जाने के बाद फ़ाइल को बंद करना न भूलें;)


4
+1, हां, कृपया अनावश्यक फ़ाइल I / O से बचने के लिए अस्थायी चर को पढ़ें। यह एक गलत अर्थव्यवस्था है कि आप किसी भी मेमोरी को बचा रहे हैं क्योंकि आपके पास कम (स्पष्ट) चर हैं।
निक टी

2
@ नोट: मुझे उम्मीद है कि कई बार पढ़ने वाली एक छोटी फ़ाइल ओएस (कम से कम लिनक्स / ओएसएक्स) पर कैश हो जाती है, इसलिए दो बार में पढ़ने के लिए कोई अतिरिक्त फ़ाइल I / O नहीं। मेमोरी में फिट नहीं होने वाली बड़ी फाइलें कैश नहीं होती हैं, लेकिन आप उन्हें एक चर में पढ़ना नहीं चाहते हैं क्योंकि आप स्वैप करना शुरू कर देंगे। इसलिए संदेह के मामले में, हमेशा कई बार पढ़ें। यदि आप सुनिश्चित करते हैं कि फाइलें छोटी हैं, तो सबसे अच्छा प्रोग्राम दें।
क्लाउड

3
आंसू नीचे के साथ स्वचालित किया जा सकता है with
सेस टिम्मरमैन

30

हाँ, जैसा कि ऊपर ...

मैं सिर्फ एक उदाहरण लिखूंगा:

>>> a = open('file.txt')
>>> a.read()
#output
>>> a.seek(0)
>>> a.read()
#same output

17

हर कोई जिसने इस सवाल का जवाब दिया है वह बिल्कुल सही है - read()फ़ाइल के माध्यम से चलता है, इसलिए इसे कॉल करने के बाद, आप इसे फिर से कॉल नहीं कर सकते।

मैं जो कुछ जोड़ूंगा वह यह है कि आपके विशेष मामले में, आपको फ़ाइल को फिर से शुरू करने या फिर से खोलने की आवश्यकता नहीं है, आप बस उस पाठ को संग्रहीत कर सकते हैं जिसे आपने स्थानीय चर में पढ़ा है, और इसे दो बार उपयोग करें, या जितनी बार आप चाहें, अपने कार्यक्रम में:

f = f.open()
text = f.read() # read the file into a local variable
# get the year
match = re.search(r'Popularity in (\d+)', text)
if match:
  print match.group(1)
# get all the names
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', text)
if matches:
  # matches will now not always be None

1
+1 वास्तव में यह इस अभ्यास के लिए प्रस्तावित समाधान था ( code.google.com/intl/de-DE/edu/languages/google-python-class/… )। लेकिन किसी तरह मैंने स्ट्रिंग को एक चर में संग्रहीत करने के बारे में नहीं सोचा। डी 'ओह!
हेल्परमेथोड

1
पायथन 3 के साथ, पाथलिब का उपयोग करें। from pathlib import Path; text = Path(filename).read_text()खुले, करीबी, आदि की देखभाल करता है
पॉलमाकग


2

प्रत्येक खुली फ़ाइल में एक संबद्ध स्थान होता है।
जब आप पढ़ते हैं () आप उस स्थिति से पढ़ते हैं। उदाहरण के लिए read(10)एक नई खुली फ़ाइल से पहले 10 बाइट्स read(10)पढ़ता है , फिर दूसरा अगले 10 बाइट्स को पढ़ता है। read()बिना तर्क के फ़ाइल के सभी सामग्री को पढ़ता है, फ़ाइल के अंत में फ़ाइल की स्थिति को छोड़ देता है। अगली बार जब आप फोन करेंगे read()तो पढ़ने के लिए कुछ नहीं है।

आप seekफ़ाइल स्थिति को स्थानांतरित करने के लिए उपयोग कर सकते हैं । या शायद आपके मामले में बेहतर यह होगा कि आप एक खोज करें read()और दोनों खोजों का परिणाम रखें।


1

read() खपत करता है । तो, आप फ़ाइल को रीसेट कर सकते हैं , या फिर से पढ़ने से पहले शुरू करना चाहते हैं । या, यदि यह आपके कार्य को सूट करता है, तो आप read(n)केवल nबाइट्स का उपभोग करने के लिए उपयोग कर सकते हैं ।


1

मैं हमेशा पढ़ी हुई विधि को एक अंधेरी गली में टहलने के लिए खोजता हूं। आप थोडा नीचे जाते हैं और रुक जाते हैं लेकिन अगर आप अपने कदम नहीं गिन रहे हैं तो आप निश्चित नहीं हैं कि आप कितने दूर हैं। सीक रिपॉजिट करके समाधान देता है, दूसरा विकल्प यह बताता है कि फाइल के साथ कौन सी स्थिति वापस आती है। हो सकता है कि पायथन फाइल एपी इसे सरल बनाने के लिए read_from (स्थिति, बाइट्स) में पढ़ सकते हैं और जोड़ सकते हैं - तब तक जब तक आपको यह पृष्ठ नहीं पढ़ना चाहिए ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.