अजगर में एक फ़ाइल को पढ़ने की कोशिश करते समय अपवादों को संभालने का एक अच्छा तरीका क्या है?


86

मैं अजगर में .csv फ़ाइल पढ़ना चाहता हूं।

  • मुझे नहीं पता कि फ़ाइल मौजूद है या नहीं।
  • मेरा वर्तमान समाधान नीचे है। यह मेरे लिए टेढ़ा लगता है क्योंकि दो अलग-अलग अपवाद परीक्षण अजीब रूप से रसपूर्ण हैं।

क्या ऐसा करने का कोई पूर्व तरीका है?

import csv    
fName = "aFile.csv"

try:
    with open(fName, 'rb') as f:
        reader = csv.reader(f)
        for row in reader:
            pass #do stuff here
    
except IOError:
    print "Could not read file:", fName

यदि एक गैर-मौजूदा फ़ाइल एक त्रुटि मामला नहीं है, लेकिन एक संभावित परिस्थिति है, तो उसकी अनुपस्थिति / गैर-पठनीयता को स्पष्ट रूप से (और इसके अतिरिक्त ) के लिए जाँच करना और इसके tryलायक हो सकता है। इसके साथ os.path.exists(file)और os.access(file, os.R_OK)क्रमशः किया जा सकता है । इस तरह की जाँच कभी भी दौड़ की स्थिति से मुक्त नहीं हो सकती है, लेकिन लुप्त हो रही फाइलें शायद ही कभी एक सामान्य परिस्थिति होती हैं;)
स्टीफनैक्ट

2
इस प्रश्न के उत्तर को संभवतः pathlibमॉड्यूल के उपयोग को शामिल करने के लिए अद्यतन किया जाना चाहिए , जो इस समस्या को बहुत आसान बनाता है, और शायद मानक पायथन अभ्यास होना चाहिए (विशेषकर चूंकि यह 2.7 के लिए भी बैकपोर्ट किया गया था)।
रिक

जब यह पकड़ता है IOError, तो यह csv.ErrorCSV प्रारूप फ़ाइल के कारण Dialect.strict=Trueया Errorकिसी अन्य त्रुटि (CSV पैकेज डॉक्स के अनुसार) नहीं होने के कारण पकड़ नहीं पाता है , इसलिए एक बाहरी कोशिश, या बस फ़ाइल की जाँच करना मौजूद है, तो CSV अपवादों के लिए एक आंतरिक प्रयास है। शायद सही जवाब।
गुलाबी स्पाइकहाइरमैन

@pinkspikyhairman हां, अपने हैंडलर को छोड़कर, आपको यह तय करना होगा कि आप किस त्रुटि प्रकार को संभालना चाहते हैं। कई विशिष्ट प्रकार की त्रुटियों से निपटने के तरीके के लिए यहां देखें: stackoverflow.com/questions/6470428/…
चार्ल्स होलब्रो

जवाबों:


52

मुझे लगता है कि मुझे गलत समझा गया था कि क्या पूछा जा रहा है। री-री-रीडिंग, ऐसा लगता है कि टिम का जवाब है कि आप क्या चाहते हैं। मुझे अभी इसे जोड़ने दें, हालांकि: यदि आप एक अपवाद को पकड़ना चाहते हैं open, तो openएक में लपेटा जाना होगा try। यदि कॉल opena के हेडर में है with, तो withए में होना चाहिएtry अपवाद को पकड़ने के । उसके आसपास कोई रास्ता नहीं है।

तो इसका जवाब है: "टिम का रास्ता" या "नहीं, आप इसे सही तरीके से कर रहे हैं।"


पिछला अनसुना उत्तर जिसका सभी टिप्पणियाँ उल्लेख करते हैं:

import os

if os.path.exists(fName):
   with open(fName, 'rb') as f:
       try:
           # do stuff
       except : # whatever reader errors you care about
           # handle error


23
सिर्फ इसलिए कि एक फ़ाइल मौजूद है इसका मतलब यह नहीं है कि आप इसे पढ़ सकते हैं!
गाबे

3
यह सही नहीं है, क्योंकि यह संभव है कि फ़ाइल को हटा दिया जाता है (जैसे कि किसी अन्य प्रक्रिया द्वारा) यह जाँचने के बीच कि यह मौजूद है और इसे खोलने की कोशिश कर रहा है।
लिक्विड_फायर

शायद मैं सवाल गलत समझ रहा हूं। वास्तव में, मुझे लगता है कि मैं निश्चित रूप से हूं।
jscs

1
यह भी संभव है कि fNameकुछ फ़ाइल का नाम हो सकता है, भले ही वह चारों ओर चिपक जाए, जो भी कारण के लिए खोला नहीं जा सकता है - उदाहरण के लिए, यदि यह एक निर्देशिका है या इसके पास निष्पादन की प्रक्रिया द्वारा पढ़ने की अनुमति नहीं है।
intuited

4
"यदि मौजूद है (फ़ाइल): ओपन (फ़ाइल)" विधि विफल हो सकती है क्योंकि फ़ाइल को हटाने के बाद आप देख सकते हैं कि यह मौजूद है लेकिन इसे खोलने से पहले। या इसे लॉक किया जा सकता है, या पढ़ने की अनुमति नहीं है, या कुछ प्रकार की वस्तु हो जिसे आप पढ़ नहीं सकते हैं (जैसे एक निर्देशिका), या टेप पर संग्रहीत किया जा सकता है और टेप उपलब्ध नहीं है, या कोई डिस्क त्रुटि हो सकती है। फ़ाइल खोलने की कोशिश कर रहा है, या ...
गाबे

64

इस बारे में कैसा है:

try:
    f = open(fname, 'rb')
except OSError:
    print "Could not open/read file:", fname
    sys.exit()

with f:
    reader = csv.reader(f)
    for row in reader:
        pass #do stuff here

10
इसके साथ एकमात्र समस्या यह है कि फ़ाइल withब्लॉक से बाहर खोली गई है। इसलिए यदि tryकॉल openऔर withस्टेटमेंट वाले ब्लॉक के बीच कोई अपवाद होता है , तो फ़ाइल बंद नहीं होती है। इस मामले में, जहां चीजें बहुत सरल हैं, यह एक स्पष्ट मुद्दा नहीं है, लेकिन यह तब भी खतरा पैदा कर सकता है जब कोड को फिर से भरना या अन्यथा संशोधित करना। कहा जा रहा है, मुझे नहीं लगता कि ऐसा करने का एक बेहतर तरीका है (मूल संस्करण के अलावा)।
intuited

2
@intuited: यह सही है। वास्तव में, ओपी का अंतिम उत्तर शायद सिर्फ: नहीं, जिस तरह से आपने किया है वह सही तरीका है।
jscs

1
FileNotFoundError.mro() है [<class 'FileNotFoundError'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]और IOError.mro()है [<class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]। कैसे के बारे में OSErrorया Exceptionइसके बजाय का उपयोग कर ? `` `
हॉटहोटो

1
@hotohoto: अच्छा विचार है। मुझे यकीन नहीं है - शायद 2011 से इस संबंध में अपवाद पदानुक्रम बदल गया है, लेकिन वैसे भी आपका सुझाव अधिक शामिल है।
टिम पीटरज़

16

यहाँ एक पढ़ा / लिखा उदाहरण है। स्टेटमेंट्स के साथ क्लोज़ () स्टेटमेंट को फ़ाइल ऑब्जेक्ट द्वारा बुलाया जाएगा, भले ही कोई अपवाद फेंका गया हो। http://effbot.org/zone/python-with-statement.htm

import sys

fIn = 'symbolsIn.csv'
fOut = 'symbolsOut.csv'

try:
   with open(fIn, 'r') as f:
      file_content = f.read()
      print "read file " + fIn
   if not file_content:
      print "no data in file " + fIn
      file_content = "name,phone,address\n"
   with open(fOut, 'w') as dest:
      dest.write(file_content)
      print "wrote file " + fOut
except IOError as e:
   print "I/O error({0}): {1}".format(e.errno, e.strerror)
except: #handle other exceptions such as attribute errors
   print "Unexpected error:", sys.exc_info()[0]
print "done"

इस मामले में, IOError स्पष्ट है, लेकिन कोड कवरेज के दृष्टिकोण से सामान्य अपवाद कब होगा। मैं एक सामान्य अपवाद उत्पन्न करने के लिए टेस्ट केस कैसे बना सकता हूं।
मियां असबत अहमद

0
fname = 'filenotfound.txt'
try:
    f = open(fname, 'rb')
except FileNotFoundError:
    print("file {} does not exist".format(fname))

file filenotfound.txt does not exist

अपवाद FileNotFoundError जब किसी फ़ाइल या निर्देशिका का अनुरोध किया जाता है, तो मौजूद होती है, लेकिन मौजूद नहीं होती है। गलत करने के लिए अनुरूप है।

https://docs.python.org/3/library/exception.html
यह अपवाद पायथन 2 में मौजूद नहीं है।


1
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन समस्या को हल करने के तरीके के बारे में अतिरिक्त संदर्भ प्रदान करता है और यह समस्या को हल करता है ताकि उत्तर के दीर्घकालिक मूल्य में सुधार हो सके।
डोनाल्ड डक

-12

@ जोश के उदाहरण में जोड़ना;

fName = [FILE TO OPEN]
if os.path.exists(fName):
    with open(fName, 'rb') as f:
        #add you code to handle the file contents here.
elif IOError:
    print "Unable to open file: "+str(fName)

इस तरह से आप फ़ाइल को खोलने का प्रयास कर सकते हैं, लेकिन यदि यह मौजूद नहीं है (यदि यह IOError बढ़ाता है), तो उपयोगकर्ता को सचेत करें!


समस्या को देखकर नहीं। यदि यह गलत सिंटैक्स होता तो इसे निष्पादित करते समय एक सिंटैक्स त्रुटि होती!
ज़ैक ब्राउन

7
सिंटैक्स त्रुटि नहीं, लेकिन bool(IOError)बस है Trueऔर ifकोई अपवाद नहीं पकड़ता है।

8
>>> if IOError: print "That's not an exception handler"
jscs

3
@ जोश कैसवेल सही है। IOError True पर मूल्यांकन करता है। docs.python.org/2.4/lib/truth.html
hecvd
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.