파이썬에서 파일을 읽으려고 할 때 예외를 처리하는 좋은 방법은 무엇입니까?


84

파이썬으로 .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로 백 포트 되었기 때문에).
릭 모니카 지원

이것이 catch하는 동안 파일이 CSV 형식이 아니기 때문에 또는 다른 오류 (CSV 패키지 문서에 따라)에 대해 IOErrorcatch하지 않으므로 외부 시도 또는 단순히 파일 확인이 존재하면 CSV 예외에 대한 내부 시도는 다음과 같습니다. 아마도 정답 일 것입니다. csv.ErrorDialect.strict=TrueError
분홍색 spikyhairman

@pinkspikyhairman 예, 예외 처리기에서 처리 할 오류 유형을 결정해야합니다. 여러 특정 유형의 오류를 처리하는 방법은 여기를 참조하십시오. stackoverflow.com/questions/6470428/…
Charles Holbrow

답변:


50

질문받은 내용을 오해 한 것 같습니다. 다시 읽으면 Tim의 대답이 당신이 원하는 것 같습니다. 나 그냥하지만,이를 추가하자 : 당신이에서 예외를 잡을하려는 경우 open, 다음 openA의 포장되어야한다 try. 호출이 경우 opena의 헤더에 with, 다음은 withA의이어야 try예외를 잡을 수 있습니다. 그 주위에는 방법이 없습니다.

그래서 대답은 "Tim 's way"또는 "No, you 're doing it right."입니다.


모든 댓글이 참조하는 이전의 도움이되지 않은 답변 :

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


21
파일이 존재한다고해서 읽을 수 있다는 의미는 아닙니다!
Gabe

3
파일이 존재하는지 확인하고 열려는 사이에 파일이 삭제 될 수 있기 때문에 (예 : 다른 프로세스에 의해) 완벽하지 않습니다.
Liquid_Fire

아마도 나는 질문을 오해하고있을 것입니다. 사실 저는 확실히 그렇다고 생각합니다.
jscs 2011

1
또한 fName파일이 붙어 있어도 어떤 이유로 든 열 수없는 일부 파일의 이름이 될 수 있습니다. 예를 들어 디렉토리이거나 실행중인 프로세스에서 읽을 수있는 권한이없는 경우입니다.
intuited

4
"if exist (file) : open (file)"메서드는 파일이 있는지 확인한 후 파일을 열기 전에 제거 할 수 있기 때문에 실패 할 수 있습니다. 또는 잠겨 있거나 읽기 권한이 없거나 읽을 수없는 (예 : 디렉터리) 개체 유형이거나 테이프에 보관되고 테이프를 사용할 수 없거나 디스크 오류가있을 수 있습니다. ... 파일을 열려고 시도, 또는
게이브

62

이건 어때:

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호출을 포함 하는 블록 openwith문 사이에 예외가 발생 하면 파일이 닫히지 않습니다. 이 경우 상황이 매우 간단한 경우 명백한 문제는 아니지만 코드를 리팩토링하거나 수정할 때 여전히 위험 할 수 있습니다. 즉,이 작업을 수행하는 더 좋은 방법은 없다고 생각합니다 (원래 버전 이외).
intuited

2
@intuited : 맞습니다. 실제로 OP에 대한 최종 답변은 아마도 다음과 같습니다. 아니요, 당신이 한 방식이 올바른 방식입니다.
jscs 2011

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대신 사용 하는 것은 어떻습니까? ```
hotohoto

1
@hotohoto : 좋은 생각입니다. 잘 모르겠습니다. 2011 년 이후로 예외 계층 구조가 이와 관련하여 변경되었지만 어쨌든 귀하의 제안은 더 포괄적입니다.
Tim Pietzcker 19 년

16

다음은 읽기 / 쓰기 예입니다. with 문은 예외 발생 여부에 관계없이 close () 문이 파일 객체에 의해 호출되도록합니다. 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"

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

file filenotfound.txt does not exist

exception FileNotFoundError 파일 또는 디렉토리가 요청되었지만 존재하지 않을 때 발생합니다. errno ENOENT에 해당합니다.

https://docs.python.org/3/library/exceptions.html
이 예외는 Python 2에 없습니다.


1
이 코드가 질문에 답할 수 있지만 문제를 해결하는 방법 및 / 또는 이유에 대한 추가 컨텍스트를 제공하면 답변의 장기적인 가치가 향상됩니다.
Donald Duck

-11

@Josh의 예에 추가;

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가 발생하는 경우) 사용자에게 경고합니다!


문제가 보이지 않습니다. 구문이 올바르지 않으면 실행시 구문 오류가 발생합니다!
Zac Brown

7
구문 오류는 아니지만 bool(IOError)간단 True하고 if예외를 포착하지 않습니다.

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

3
@Josh Caswell이 맞습니다. IOError는 True로 평가됩니다. docs.python.org/2.4/lib/truth.html
hecvd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.