파이썬에서 예외처리 방법에대해 정리해보고자 합니다. 제 메인 언어는 C++인데 파이썬은 C++과 다소 다른부분이 있어서 다른부분을 짚어보고, 파이썬 예외처리 제대로 사용하는방법을 알아보려 합니다.
C++ 예외처리
C++ 에서는 아래코드처럼 try catch가 전부이고 문법구조가 간단하기때문에 사용법도 간단합니다. 물론 코드가 길어지는 단점은 있습니다. C++은 아래처럼 사용합니다.
try {
// 예외 가능성이 있는 코드 작성
throw std::runtime_error("0으로 나눌 수 없습니다!")
}
catch (... ) {
// 예외처리
}
Python 예외처리
# 예외처리 try 구문 작동원리
try:
print("1. 예외가 발생될 수 있다고 예상되는 코드")
# raise exception() # <- 임의로 에러 발생!!
except:
print("2. 에러가 발생 하였습니다")
else:
print("3. 에러가 없을 때 실행할 코드")
finally:
print("4. 에러 유무 관계없이 실행할 코드")
파이썬은 try: exception: 의 C++ 의 try, catch에 대응하는 기능인데, 이 둘은 필수로 작성하고 else문과 finally문은 (optional)한 코드입니다. 하지만 구조가 이렇게 잡혀있는만큼 따르면 얻는 잇점도 있기때문에 그 부분을 알고 넘어가고자 합니다.
try:
try문은 파일 입출력이나 네트워크와 연결된 에러가 예상되는 코드를 작성해줍니다.
except:
except에서는 catch와 마찬가지로 에러가 발생한경우 디버깅용 또는 로그용 코드를 작성해도 좋고 에러 알림용 코드를 작성해도 좋습니다.
else: (optional)
이곳은 try문이 성공했을때 실행될 코드를 작성해줍니다. C++과 차이가있다면, C++에서는 try문에 파일 읽는 코드가 있다면, catch문 아래에 파일 객체를 담은 변수를 if문으로 체크해서 try가 성공한것을 확인하고 파일객체를 사용하거나 try가 실패한것을 확인하여 바로 파일을 닫는 등 코드를 작성해야합니다.
파이썬에서는 else: 키워드자체가 파일 읽어오기가 성공되었다는것을 보장해주므로 파일읽기 성공여부를 체크하지 않아도 됩니다. 물론 파일을 읽어온 데이터의 무결성검사는 여전히 해줄 필요가 있습니다.
finally: (optional)
이곳은 예외발생여부와 상관없이 try 예외처리 구문 마지막에 실행되는 코드인데요. try문에서 파일을 읽어왔다면 이곳에서 파일을 닫는 코드가 들어가면 좋습니다.
C++ 사용자라면 else문 finally문 없이 그냥 쓰면 되는거아니야 라고 생각될수도있는데, 예외가 발생할수있는 코드부분을 묶어주면 가독성에도 도움이되고 위에 else 부분에서 언급한것처럼 if문 사용을 줄이는데도 도움이 됩니다.
Python 사용자 입장에서 예외처리 예시
C++과 비교하면 파이썬 예외처리구문의 기능을 전부 다룰수없어서 순수 파이썬 사용자 입장에서도 예시를 한번 살펴보겠습니다.

예시코드는 위 사진처럼 웹사이트에서 학점조회를 할경우 백엔드 데이터얻어오는 코드를 예시로 들었습니다. 아래의 코드 2번을 집중해서 봐주세요 설명은 아래서 이어 하겠습니다.
#[코드 1]
scores = {"유원영": {"국어": 94, "영어": 91, "수학": 89},
"설지민": {"국어": 88, "영어": 96, "수학": 90},
"신윤아" :{"국어":86, "영어":88, "수학": 77},
"장윤아": {"국어": 98, "영어": 76, "수학": 92}}
def score_analysis(data, name):
print(f"[{name} 성적 분석]")
for 과목 in ["국어", "영어", "수학"]:
합계 = 0
for i in data:
합계 += data[i][과목]
학급평균 = 합계 / len(data)
내점수= data[name][과목]
편차=내점수-학급평균
print(f"{과목}:{내점수}점, 학급평균({학급평균}점, 편차= {편차:+})")
print("\n")
#[코드 2]
def query_test_result(name):
try:
print("1. 성적표 데이터 불러오기를 시도합니다.\n")
# f = open("~/work/workplace/파이썬/성적표.txt", "r") # 파일 불러오기 or 데이터 베이스 쿼리
except:
print("2. 성적표 데이터 불러오기 중 알수 없는 오류 발생\n") # 로깅 및 디버깅 용
print("[시스템에러]: 잠시 후 다시 시도해 주세요.\n") # 사용자에게 알림 용
else:
print("3. 성적표 데이터 불러오기 성공\n") # 로깅 및 디버깅 용
print("[조회성공]: 시험결과를 출력합니다\n") # 사용자에게 알림 용
#10/0 # <- 에러발생 유발
data = scores # data = f.read() # 또는 DB 쿼리
score_analysis(data, name)
finally:
print("4. 파일을 닫습니다.\n")
#f.close() # <- "Graceful Shutdown" (우아한 종료)
query_test_result("장윤아")
try 에서는 예외가 발생할수있는 데이터베이스 쿼리나 파일입출력같은 코드가 들어가면 좋습니다. 예시에서는 파일 불러오는 코드가 있습니다.
except: 예외가 발생한경우 loggin debugging 용 메시지 출력과함께 사용자 알림 메시지 출력 or 전송 기능을 넣을수있습니다.
else: 파일 읽기가 성공한경우에만 실행되기때문에 또다른 점검없이 f.read()로 파일속 데이터를 읽어오는것을 볼수있습니다.
finally:에서는 f.close()로 파일을 닫는것을 알수있습니다.
else는 왜 필요한가?
- (예외처리 구문 밖은 안됨) 현재 예제코드에서는 파일읽기를 성공했다고 가정하고 f.read()를 사용하는데, 이를 try구문이 끝나고나서 사용할경우. 파일읽기가 실패한경우에도 f.read()를 호출해서 에러가 발생하게 됩니다.
- (try: 구문에서는 안됨) try구문안에 f.read()가있으면 문제없이 모든게 잘 작동하면 상관없겠지만, f.read()를하다가 에러가 발생하게되거나 혹은 다른 코드 (예시에서는 score_analysis(data, name) 이부분에서) 에러가 나더라도 어디서 에러나는지 알수가 없습니다.
finally는 왜필요한가?
- finally는 파일닫기처럼 try문에서 파일을 열었을때 꼭 수행되야하는 작업을 넣어줍니다.
- try 구문 어딘가에서 return이나 break를 통해 try를 빠져나가는것을 시도하면 finally 문이 실행되는것을 보장해줍니다.