जवाबों:
उस प्रश्न का उत्तर कुछ विशेष रूप से पायथन कार्यान्वयन पर निर्भर करता है।
यह समझने के लिए कि यह सब क्या है, वास्तविक file
वस्तु पर विशेष ध्यान दें । आपके कोड में, उस ऑब्जेक्ट का उल्लेख केवल एक बार किया जाता है, एक अभिव्यक्ति में, और read()
कॉल रिटर्न के तुरंत बाद दुर्गम हो जाता है।
इसका मतलब है कि फ़ाइल ऑब्जेक्ट कचरा है। केवल शेष प्रश्न "कचरा कलेक्टर फ़ाइल ऑब्जेक्ट को कब एकत्र करेगा?"।
सीपीथॉन में, जो एक संदर्भ काउंटर का उपयोग करता है, इस तरह का कचरा तुरंत देखा जाता है, और इसलिए इसे तुरंत एकत्र किया जाएगा। यह आमतौर पर अन्य अजगर कार्यान्वयनों के बारे में सच नहीं है।
एक बेहतर समाधान, यह सुनिश्चित करने के लिए कि फ़ाइल बंद है, क्या यह पैटर्न है:
with open('Path/to/file', 'r') as content_file:
content = content_file.read()
जो हमेशा ब्लॉक समाप्त होने के तुरंत बाद फ़ाइल को बंद कर देगा; भले ही कोई अपवाद हो।
संपादित करें: इस पर एक महीन बिंदु डालने के लिए:
अन्य के अलावा file.__exit__()
, जो "स्वचालित रूप से" एक with
संदर्भ प्रबंधक सेटिंग में कहा जाता है , एकमात्र तरीका है file.close()
जिसे स्वचालित रूप से कहा जाता है (अर्थात, स्पष्ट रूप से खुद को कॉल करने के अलावा,) file.__del__()
। यह हमें इस सवाल की ओर ले जाता है कि हमें कब __del__()
बुलाया जाता है?
एक सही ढंग से लिखा कार्यक्रम यह नहीं मान सकता है कि कार्यक्रम समाप्ति से पहले कभी भी अंतिम बिंदु किसी भी बिंदु पर चलेगा।
- https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203
विशेष रूप से:
वस्तुओं को कभी भी स्पष्ट रूप से नष्ट नहीं किया जाता है; हालांकि, जब वे पहुंच से बाहर हो जाते हैं, तो वे कचरा एकत्र किए जा सकते हैं। कचरा संग्रहण को स्थगित करने या इसे पूरी तरह से छोड़ने के लिए एक कार्यान्वयन की अनुमति दी जाती है - यह कार्यान्वयन गुणवत्ता का मामला है कि कचरा संग्रह कैसे लागू किया जाता है, जब तक कि कोई भी वस्तु एकत्र नहीं की जाती है जो अभी भी उपलब्ध हैं।
[...]
CPython वर्तमान में एक संदर्भ-गणना योजना का उपयोग करता है, जिसके साथ (वैकल्पिक) विलंबित रूप से लिंक किए गए कचरे का पता लगाने में देरी होती है, जो ज्यादातर वस्तुओं को इकट्ठा करते हैं जैसे ही वे पहुंच से बाहर हो जाते हैं, लेकिन परिपत्र संदर्भ वाले कचरे को इकट्ठा करने की गारंटी नहीं है।
- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-ypes
(जोर मेरा)
लेकिन जैसा कि यह सुझाव है, अन्य कार्यान्वयन अन्य व्यवहार हो सकता है। एक उदाहरण के रूप में, PyPy में 6 अलग-अलग कचरा संग्रह कार्यान्वयन हैं !
__exit__()
ऐसे मामलों में कॉल न करना एक डिज़ाइन दोष की तरह लगता है।
try
/ finally
जमकर हो रहा है और सफाई करने वाले हैंडलर्स की अत्यधिक सामान्य उपयोगी है जो with
हल करता है। "स्पष्ट रूप से समापन" और "के साथ प्रबंधन" के बीच का अंतर यह with
है कि अपवाद हैंडलर को अपवाद कहे जाने पर भी कहा जाता है। आप इसे close()
एक finally
क्लॉज़ में डाल सकते हैं , लेकिन with
इसके बजाय इसका उपयोग करने से बहुत अलग नहीं है , थोड़ा गड़बड़ (1 के बजाय 3 अतिरिक्त लाइनें), और बस सही पाने के लिए थोड़ा कठिन है।
with foo() as f: [...]
मूल रूप से रूप में ही है f = foo()
, f.__enter__()
, [...] और f.__exit__()
संभाला अपवादों के साथ , ताकि __exit__
हमेशा कहा जाता है। तो फ़ाइल हमेशा बंद हो जाती है।
आप पाथलिब का उपयोग कर सकते हैं ।
पायथन 3.5 और उससे अधिक के लिए:
from pathlib import Path
contents = Path(file_path).read_text()
पायथन के पुराने संस्करणों के लिए pathlib2 का उपयोग करें :
$ pip install pathlib2
फिर:
from pathlib2 import Path
contents = Path(file_path).read_text()
यह वास्तविक read_text
कार्यान्वयन है :
def read_text(self, encoding=None, errors=None):
"""
Open the file in text mode, read it, and close the file.
"""
with self.open(mode='r', encoding=encoding, errors=errors) as f:
return f.read()
ठीक है, अगर आपको प्रत्येक पंक्ति के साथ काम करने के लिए लाइन से फाइल लाइन पढ़ना है, तो आप उपयोग कर सकते हैं
with open('Path/to/file', 'r') as f:
s = f.readline()
while s:
# do whatever you want to
s = f.readline()
या इससे भी बेहतर तरीका:
with open('Path/to/file') as f:
for line in f:
# do whatever you want to
फ़ाइल सामग्री को एक स्ट्रिंग के रूप में पुनर्प्राप्त करने के बजाय, सामग्री को संग्रहीत करना आसान हो सकता है क्योंकि फ़ाइल में सभी पंक्तियों की सूची शामिल है :
with open('Path/to/file', 'r') as content_file:
content_list = content_file.read().strip().split("\n")
जैसा कि देखा जा सकता है, इस धागे में मुख्य उत्तर में संक्षिप्त तरीकों .strip().split("\n")
को जोड़ने की आवश्यकता है ।
यहाँ, .strip()
पूरे फाइल स्ट्रिंग के अंत में सिर्फ व्हाट्सएप और न्यूलाइन वर्णों को हटाता है, और .split("\n")
प्रत्येक न्यूलाइन वर्ण \ n पर संपूर्ण फ़ाइल स्ट्रिंग को विभाजित करके वास्तविक सूची तैयार करता है ।
इसके अलावा, इस तरह से पूरी फ़ाइल सामग्री को एक चर में संग्रहित किया जा सकता है, जो कुछ मामलों में वांछित हो सकती है, बजाय इस पिछले उत्तर में बताए फ़ाइल लाइन पर लूपिंग के बजाय ।