2009-12-02 12 views
28

यह बुरा व्यवहार निम्न और नहीं स्पष्ट रूप से एक फ़ाइल वस्तु संभाल और उसके close() विधि कॉल करने के लिए है?पास() आवश्यक है

for line in open('hello.txt'): 
    print line 

एनबी - इस अजगर के संस्करणों कि अभी तक with बयान की जरूरत नहीं है के लिए है।

मैं अजगर प्रलेखन इस सिफारिश करने के लिए लगता है के रूप में पूछते हैं: -

f = open("hello.txt") 
try: 
    for line in f: 
     print line 
finally: 
    f.close() 

कौन सा आवश्यकता से अधिक वर्बोज़ लगता है।

उत्तर

2

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

+0

यह अभी भी आम तौर पर अच्छा अभ्यास माना जाता है फ़ाइल बंद हुआ। मुझे लगता है कि यह वास्तव में एक या दो फाइलें खोलने के लिए कुछ भी नुकसान नहीं पहुंचाएगा, लेकिन यह * यह * बंद करने के लिए बहुत अधिक काम नहीं है। –

1

हां, क्योंकि अन्यथा आप संसाधनों को रिसाव कर सकते हैं।

आप एक फ़ाइल के साथ किया कर रहे हैं, कहते हैं f.close() इसे बंद करना और मुक्त किसी भी सिस्टम संसाधन खुला फ़ाइल द्वारा लिया।

Python docs से।

यह प्रोग्राम आपके बाहर आने पर आपके लिए होगा, लेकिन अन्यथा पाइथन संसाधनों के आस-पास रखते हुए इसे अब उस बिंदु तक की आवश्यकता नहीं है।

4

पायथन दुभाषिया (या क्रैश की स्थिति में कर्नेल) से बाहर निकलने पर फ़ाइल बंद हो जाएगी, लेकिन जब भी आपको उनकी आवश्यकता नहीं होती है तब भी उन्हें बंद करने के लिए यह एक अच्छा अभ्यास है। 1 या 2, या 10 के लिए, फाइलें यह समस्या नहीं हो सकती हैं, लेकिन अधिक के लिए यह पूरी प्रणाली को नीचे ला सकती है।

सबसे महत्वपूर्ण बात यह है कि यह संकेत है कि जिस व्यक्ति ने वास्तव में कोड लिखा था, उसके काम के बारे में परवाह करता है।

+2

दरअसल, आपको प्रक्रिया को रोकने के लिए भी इंतजार नहीं करना पड़ता है। कचरा इकट्ठा होने पर यह बंद हो जाएगा। अधिक जानकारी के लिए मेरा जवाब देखें। छोटे, लघु चलने वाली स्क्रिप्ट में –

5

यह जगह पर संकेत दिया गया है, लेकिन इसे सबसे स्पष्ट बनाने के लिए, हाँ, आपको उस फ़ाइल को बंद करने की आवश्यकता है। अजगर 2.5 में (भविष्य प्रयोग करके) और अजगर 2.6 में, आप अब अधिक शब्दों वाले संस्करण की आवश्यकता:

from __future__ import with_statement 
with open("hello.txt") as f: 
    for line in f: 
     print line 
52

बंद है हमेशा आवश्यक जब फाइलों के साथ काम कर रहा है, यह एक अच्छा विचार है फ़ाइल खोलने को छोड़ने के लिए नहीं है पूरे स्थान पर हैंडल करता है। फ़ाइल ऑब्जेक्ट कचरा इकट्ठा होने पर वे अंततः बंद हो जाएंगे, लेकिन आपको नहीं पता कि यह कब होगा और इस समय आप फाइल हैंडल को पकड़कर सिस्टम संसाधनों को बर्बाद कर देंगे, अब आपको इसकी आवश्यकता नहीं है।

आप अजगर 2.5 और उपयोग कर रहे हैं उच्च close() आप स्वचालित रूप से with कथन का उपयोग के लिए कहा जा सकता है:

f = open("hello.txt") 
try: 
    for line in f: 
     print line 
finally: 
    f.close() 
:

from __future__ import with_statement # Only needed in Python 2.5 
with open("hello.txt") as f: 
    for line in f: 
     print line 

यह वह जगह है कोड आप जैसा ही होता है

with कथन Resource Acquisition Is Initialization मुहावरे के लिए सीधा भाषा समर्थन आमतौर पर सी ++ में उपयोग किया जाता है।यह सभी प्रकार के संसाधनों के सुरक्षित उपयोग और सफाई की अनुमति देता है, उदाहरण के लिए इसका उपयोग यह सुनिश्चित करने के लिए किया जा सकता है कि डेटाबेस कनेक्शन बंद हैं या ताले हमेशा नीचे की तरह जारी किए जाते हैं।

mylock = threading.Lock() 
with mylock: 
    pass # do some thread safe stuff 
+2

यह थोड़े समय के लिए एक फ़ाइल खोलने फांसी arodund होने के खिलाफ कोड की स्पष्टता बंद व्यापार करने के लिए विवेकपूर्ण हो सकता है। – hop

+9

'साथ' कथन इतना आसान है कि स्पष्टता के हित में इसका उपयोग न करने के लिए उचित है। –

+0

सच है कि 2.5+ – hop

16

वास्तविकता में, फ़ाइल कचरा इकट्ठा होने पर बंद हो जाएगी। यह कैसे काम करता है इस पर और अधिक के लिए this question देखें।

यह अभी भी अनुशंसा की जाती है कि आप कोशिश/आखिरकार ब्लॉक या कथन के साथ उपयोग करें। यदि फ़ाइल ऑब्जेक्ट के तरीकों में से किसी एक का उपयोग करते समय कोई अपवाद है, तो एक संदर्भ ट्रेसबैक (जिसे वैश्विक चर के रूप में संग्रहीत किया जाता है) में संग्रहीत किया जाएगा जब तक कि आप इसे साफ़ नहीं करते हैं या कोई अन्य अपवाद होता है।

इस प्रकार, आपके लिए अपनी फ़ाइल बंद करने के लिए कचरा संग्रह पर भरोसा करना बुरा है।

इसके अलावा, अगर आपने फ़ाइल में लिखा है, तो आप गारंटी नहीं दे सकते कि परिवर्तन तब तक फ़ाइल में सहेजे जाएंगे जब तक कि यह बंद या फ़्लश न हो जाए।

+1

+1 बाकी के उत्तर सिर्फ दस्तावेज़ों को उद्धृत कर रहे हैं, आपने कोशिश/अंततः उपयोग करने के लिए एक अच्छी व्याख्या दी है। – Sushant

3

नहीं, मैं विश्वास नहीं है लंबे समय तक मुहावरा आवश्यक है, और यहाँ है क्यों:

मैं

के पैटर्न 'for\s+.*\s+in\s+open\(' के लिए /usr/lib/python2.6/ grepped और कई उदाहरण मिल गया
for line in open('hello.txt'): 
    print line 

और अब तक

f = open("hello.txt") 
try: 
    for line in f: 
     print line 
finally: 
    f.close() 

के शून्य उदाहरणों कि for ... in open का उपयोग मानक पुस्तकालय में फ़ाइलों की सूची के लिए नीचे देखें मुहावरा।

यह स्वाभाविक रूप से प्रश्न की ओर जाता है: अजगर डेवलपर्स मानक पुस्तकालयों में कम मुहावरा स्वीकार करते हैं, कैसे हम कुछ हमारे अपने कोड में विभिन्न का उपयोग कर यदि हमारे कोड मानक लाइब्रेरी पर निर्भर करती द्वारा कुछ भी सुधार लाने जा सकता है?

मुझे लगता है कि जवाब है, लंबे मुहावरे कुछ भी सुधार नहीं करता है।

मैं भी

#!/usr/bin/env python 
try: 
    for i,line in enumerate(open('a')): 
     print line 
     raw_input() 
     if i==5: 
      break 
except Exception: 
    pass 

raw_input() 

भाग गया और जब फ़ाइल वर्णनकर्ता बंद हो गया के लिए जाँच की /proc/PID/fd। ऐसा प्रतीत होता है कि जब आप लूप से बाहर निकलते हैं, तो फ़ाइल आपके लिए बंद होती है।

इन प्रयोगों के आधार पर, मुझे विश्वास नहीं है कि लंबे try...finally...close मुहावरे आवश्यक है।

यहाँ ग्रेप का परिणाम है:

/usr/lib/python2.6/dist-packages/NvidiaDetector/nvidiadetector.py:89:tempList = [ x.strip() for x in open(obsolete).readlines() ] 
/usr/lib/python2.6/dist-packages/rpy_io.py:49:for line in open(file).readlines(): 
/usr/lib/python2.6/dist-packages/setuptools/command/easy_install.py:1376:for line in open(self.filename,'rt'): 
/usr/lib/python2.6/dist-packages/GDebi/DscSrcPackage.py:47:for line in open(file): 
/usr/lib/python2.6/dist-packages/aptsources/distinfo.py:220:[x.strip() for x in open(value)]) 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeCache.py:989:for line in open("/proc/mounts"): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeAufs.py:100:for line in open("/proc/mounts"): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeAufs.py:205:for line in open("/proc/mounts"): 
/usr/lib/python2.6/dist-packages/DistUpgrade/distinfo.py:220:[x.strip() for x in open(value)]) 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeViewKDE.py:826:for c in open(sys.argv[2]).read(): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeConfigParser.py:45:items = [x.strip() for x in open(p)] 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:684:for line in open(cpuinfo): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:692:for line in open("/proc/mounts"): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:726:for line in open("/etc/fstab"): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:762:for line in open(fstab): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:801:for line in open("/etc/fstab"): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:874:for line in open(XORG): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeQuirks.py:939:for line in open(os.path.join(modaliasesdir,filename)): 
/usr/lib/python2.6/dist-packages/DistUpgrade/DistUpgradeController.py:1307:for line in open(template): 
/usr/lib/python2.6/dist-packages/DistUpgrade/xorg_fix_proprietary.py:23:for raw in open(xorg_source): 
/usr/lib/python2.6/dist-packages/DistUpgrade/xorg_fix_proprietary.py:58:for line in open(xorg): 
/usr/lib/python2.6/dist-packages/DistUpgrade/xorg_fix_proprietary.py:82:for line in open(xorg): 
/usr/lib/python2.6/dist-packages/jockey/oslib.py:377:for line in open(self.apt_jockey_source): 
/usr/lib/python2.6/dist-packages/jockey/oslib.py:393:for line in open(f): 
/usr/lib/python2.6/dist-packages/jockey/backend.py:651:for line in open(path): 
/usr/lib/python2.6/dist-packages/jockey/detection.py:277:for line in open(alias_file): 
/usr/lib/python2.6/dist-packages/jockey/detection.py:597:for l in open(os.path.join(path, 'uevent')): 
/usr/lib/python2.6/dist-packages/apt/cdrom.py:83:for line in open(fname): 
/usr/lib/python2.6/dist-packages/problem_report.py:1119:for line in open('/proc/mounts'): 
/usr/lib/python2.6/dist-packages/apport/packaging_impl.py:128:for line in open(f): 
/usr/lib/python2.6/dist-packages/apport/packaging_impl.py:190:for line in open(sumfile): 
/usr/lib/python2.6/dist-packages/apport/packaging_impl.py:641:for l in open('/etc/apt/sources.list'): 
/usr/lib/python2.6/dist-packages/apport/hookutils.py:190:for line in open('/proc/asound/cards'): 
/usr/lib/python2.6/dist-packages/apport/hookutils.py:290:for line in open('/var/log/syslog'): 
/usr/lib/python2.6/dist-packages/apport/hookutils.py:493:mods = [l.split()[0] for l in open(module_list)] 
/usr/lib/python2.6/dist-packages/softwareproperties/SoftwareProperties.py:597:for line in open(f): 
/usr/lib/python2.6/dist-packages/softwareproperties/gtk/SoftwarePropertiesGtk.py:883:for x in open(tmp.name): 
/usr/lib/python2.6/dist-packages/lsb_release.py:253:for line in open('/etc/lsb-release'): 
/usr/lib/python2.6/dist-packages/numpy/distutils/system_info.py:815:for d in open(ld_so_conf,'r').readlines(): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LocaleInfo.py:72:for line in open(languagelist_file): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LocaleInfo.py:187:for line in open(environment).readlines(): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LocaleInfo.py:193:for line in open(environment).readlines(): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LanguageSelector.py:125:for line in open(fname): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LanguageSelector.py:140:for line in open(fname): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LanguageSelector.py:171:for line in open(fname): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LanguageSelector.py:210:for line in open(fname): 
/usr/lib/python2.6/dist-packages/LanguageSelector/macros.py:16:for l in open(file): 
/usr/lib/python2.6/dist-packages/LanguageSelector/macros.py:37:for l in open(self.LANGCODE_TO_LOCALE): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LangCache.py:94:for l in open(self.BLACKLIST): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LangCache.py:99:for l in open(self.LANGCODE_TO_LOCALE): 
/usr/lib/python2.6/dist-packages/LanguageSelector/LangCache.py:111:for l in open(self.PACKAGE_DEPENDS): 
/usr/lib/python2.6/dist-packages/LanguageSelector/ImSwitch.py:78:for l in open(self.blacklist_file): 
+1

यह विश्लेषण एक दिलचस्प है, लेकिन यह स्पष्ट रूप से अपूर्ण है। सबसे पहले, यह गंध परीक्षण पास नहीं करता है: यदि पाइथन मानक पुस्तकालय में केवल 52 स्थान हैं जहां एक फ़ाइल खोली जाती है, तो मैं अपने जूते को पकाऊंगा और खाऊंगा। एक मामूली उदाहरण के लिए, 'लॉगिंग' मॉड्यूल अपनी' ओपन 'और' क्लोज़ 'विधियों को लागू करता है, जो आपके आरई नहीं मिलेगा। इसके अलावा: यह 'बंद' विधि लागू करता है। एक कारण है –

+0

सीपीथन रेफकाउंटिंग का उपयोग करता है और इन फ़ाइलों को निश्चित रूप से बंद कर देगा। यह समझ में आता है कि सीपीथॉन के साथ भेजे गए लाइब्रेरी को सीपीथन-विशिष्ट व्यवहार पर भरोसा करने में सक्षम है। –

+1

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

11

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

निश्चित रूप से ऐसे मामले हैं जहां इससे कोई फर्क नहीं पड़ता। यदि कोई फ़ाइल ऑब्जेक्ट गुंजाइश से बाहर हो जाता है या हटा दिया जाता है, तो अंतर्निहित फ़ाइल बंद हो जाएगी। (जब यह बंद हो जाता है तो आप जिस पायथन का उपयोग कर रहे हैं उसके विशिष्ट कार्यान्वयन पर निर्भर करता है।) यही कारण है कि आम तौर पर काफी अच्छा होने वाला है - अगर तुम्हें पता है वास्तव में जब फ़ाइल चर दायरे से बाहर जाने के लिए जा रहा है, और अगर आप जानते हैं कि आप अगर फाइल निर्धारणात्मक बंद कर दिया जाता है परवाह नहीं है।

लेकिन क्यों तुम भी अपने आप को विश्लेषण जब with बयान मौजूद है उस तरह से परेशान कर किया जाना चाहिए?

संबंधित मुद्दे