2011-10-15 5 views
31
# Open new file to write 
file = None 
try: 
    file = open(filePath, 'w') 
except IOError: 
    msg = ("Unable to create file on disk.") 
    file.close() 
    return 
finally: 
    file.write("Hello World!") 
    file.close() 

उपर्युक्त कोड किसी फ़ंक्शन से फिसल गया है। उपयोगकर्ता के सिस्टम की एक पंक्ति में एक त्रुटि रिपोर्ट कर रहा है:पायथन प्रयास करें: सिवाय इसके कि:

file.write("Hello World!") 

त्रुटि:

AttributeError: 'NoneType' object has no attribute 'write' 

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

कोई बात नहीं?

उत्तर

67

आपको finally ब्लॉक में फ़ाइल में नहीं लिखा जाना चाहिए क्योंकि except ब्लॉक द्वारा उठाए गए अपवादों को पकड़ा नहीं जाएगा।

except बैक निष्पादित करता है यदि प्रयास ब्लॉक द्वारा उठाए गए अपवाद हैं। finally ब्लॉक हमेशा जो भी होता है निष्पादित करता है।

इसके अलावा, वहाँ none करने के लिए file चर initialising के लिए कोई आवश्यकता नहीं होनी चाहिए।

except ब्लॉक में return का उपयोग finally ब्लॉक को नहीं छोड़ेगा। अपनी प्रकृति से इसे छोड़ा नहीं जा सकता है, यही कारण है कि आप वहां अपना "क्लीन-अप" कोड डालना चाहते हैं (यानी फाइल बंद करना)।

तो, आप कोशिश उपयोग करना चाहते हैं: को छोड़कर:

try: 
    with open("output", "w") as outfile: 
     outfile.write('Hello World') 
except IOError: 
    print 'oops!' 
:

try: 
    f = open("file", "w") 
    try: 
     f.write('Hello World!') 
    finally: 
     f.close() 
except IOError: 
    print 'oops!' 

एक ऐसा करने with बयान उपयोग कर रहा है की अधिक स्वच्छ रास्ता: अंत में, आप कुछ इस तरह करना चाहिए

+11

'with' बयान – gecco

+0

कोड के लिए +1, बहुत clever.i दुर्भाग्य से यह – viprs

+1

से सीख है' with' तो यह काम नहीं करेगा, अजगर 2.4 में मौजूद नहीं है। – SummerBreeze

0

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

मुझे लगता है कि आप अर्थशास्त्र को गलत समझाते हैं।

आपका तर्क "कोशिश" में होना चाहिए, आपको "छोड़कर" ब्लॉक में अपवादों का सामना करना चाहिए, और "आखिरकार" निष्पादित करता है कि आपकी विधि कैसे समाप्त हो जाती है, इसे साफ करने के लिए उपयोग करें।

1

को निष्पादित नहीं करता है (क्योंकि टाइप IOError है) यह आखिरकार हिस्सा है जो विशेषता प्रकार की एक और त्रुटि फेंकता है क्योंकि फ़ाइल = कोई नहीं।

27

यदि फ़ाइल खोला नहीं गया है, तो लाइन file = open(filePath, 'w') विफल हो जाती है, इसलिए file पर कुछ भी असाइन नहीं किया जाता है।

फिर, except खंड चलता है, लेकिन फ़ाइल में कुछ भी नहीं है, इसलिए file.close() विफल रहता है।

finally क्लॉज हमेशा चलता है, भले ही कोई अपवाद हो। और चूंकि file अभी भी कोई नहीं है आपको एक और अपवाद मिलता है।

आप finally के बजाय else क्लॉज चाहते हैं, जो केवल अपवाद होने पर ही होता है।

try: 
     file = open(filePath, 'w') 
    except IOError: 
     msg = "Unable to create file on disk." 
     return 
    else: 
     file.write("Hello World!") 
     file.close() 

क्यों else? Python docs कहते हैं:

The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.

दूसरे शब्दों में, इस write या close कॉल से एक IOError पकड़ नहीं होगा। जो अच्छा है, क्योंकि कारण "डिस्क पर फ़ाइल बनाने में असमर्थ" नहीं होना चाहिए। - यह एक अलग त्रुटि होगी, जिसे आपका कोड तैयार नहीं किया गया था। ऐसी त्रुटियों को संभालने का प्रयास न करना एक अच्छा विचार है।

+1

+1 अंडरयूज्ड ' – kindall

+0

के लिए +1 है, लेकिन अगर फ़ाइल.write() अपवाद उठाता है - जो भी खोलने के बाद पूरी तरह संभव है हालांकि इसे लिखने की अनुमति के साथ खोला गया था। कोशिश करने में सर्वश्रेष्ठ शामिल है: ब्लॉक – jenming

+1

@ जेनमिंग: ठीक है, बहुत कुछ अपवाद उठा सकता है :) आपको वास्तव में अपवादों को संभालने का प्रयास करना चाहिए, हालांकि आप उम्मीद करते हैं। यदि आप 'file.write()' से अपवादों के बारे में चिंतित हैं, तो इसे 'try' में शामिल करें; बस 'file.write ("परिणाम:% s"% do_calculation())' जैसे कुछ शामिल नहीं करना सुनिश्चित करें, क्योंकि यह 'do_calculation' से अपवाद छुपाएगा। –

3

file.write("Hello World!")

finally खंड के अंदर सहित तर्क क्या है ?? मुझे लगता है कि इसे try क्लॉज में ही रखा जाना चाहिए।

try: 
     file = open(filePath, 'w') 
     file.write("Hello World!") 
except IOError: 
     print("Unable to create file on disk.") 
finally: 
     file.close() 
0

यह हमेशा अपने तर्क या कोड है कि कोशिश ब्लॉक में एक अपवाद फेंक और अंत में संसाधन बंद करने के लिए ब्लॉक का उपयोग कर सकते लिखने के लिए सलाह दी जाती है।

+0

मूल प्रश्न के लिए अप्रासंगिक। – stackoverflowuser2010

1

आप कुछ इस तरह कर सकते हैं:

try: 
    do_some_stuff() 
finally: 
    cleanup_stuff() 
1

यहाँ आपकी समस्या का सबसे सीधा समाधान है। मैं finally ब्लॉक में file_obj != None की जांच करने के मुहावरे का उपयोग करता हूं।

वैसे, आपको अवगत होना चाहिए कि file एक पाइथन क्लास नाम है, इसलिए आपको एक अलग चर नाम चुनना चाहिए।

file = None 
try: 
    file = open(filePath, 'w') 
except IOError: 
    msg = ("Unable to create file on disk.") 
    file.close() 
    return 
finally: 
    if file != None: 
     file.write("Hello World!") 
     file.close() 
संबंधित मुद्दे