산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> python

파이썬 예외 처리 흔한 함정 피하기: 올바른 예외 처리법

파이썬 예외 처리 흔한 함정 피하기: 올바른 예외 처리법

많은 사람이 예외를 잘못 처리하는 거 봅니다. 혹시 당신도 해당될 수 있습니다. 다음 상황 익숙합니까?

코드 작성 중인데, 사용하는 라이브러리가 예외 발생시킬 수 있음. 정확히 어떤 예외인지 기억 안 남. 이 지점에서 소위 '잡아먹기(catch-all)' 블록 써서 재밌는 부분으로 넘어가기 유혹적.

목차

최악의 방법

할 수 있는 최악은 뭐든 잡는 try-except 블록 만드는 것. 잡아먹기라 함은 이런 거:

try:
    ...
except:
    pass

이런 잡아먹기 블록 나쁜 이유:

  1. 다른 어떤 예외 발생할지 모름(나중에 더 설명).
  2. pass로 에러 숨김, 로깅 안 함.

게다가 빈 except는 KeyboardInterrupt(Ctrl+C), SystemExit, 심지어 NameError까지 잡음! 그래서 다음 코드 깔끔하게 멈출 수 없음:

from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except:
        print("Don't.. stop.. me now!")

직접 해보세요. 터미널 창 닫거나 파이썬 프로세스 죽여야 이 프로그램 멈춥니다.

모든 예외 잡는 약간 나은 방법

반면 except Exception 쓰면, 여전히 너무 많은 예외 잡는 빠르고 지저분한 방법이지만, 적어도 실행 중인 프로세스 제대로 멈출 수 있음:

from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except Exception:
        print("Ok I'll stop!")

Exception 잡으면 SystemExit, KeyboardInterrupt 등 그런 예외 안 잡힘. 왜냐고요?

모든 예외는 BaseException 클래스 상속. 공식 문서: "try 문에서 특정 클래스 언급한 except 절, 그 클래스 파생 예외 클래스도 처리." 빈 except는 except BaseException과 동일, 그래서 모든 가능한 예외 잡음.

반면 Exception 클래스 정의: "모든 내장 비시스템 종료 예외 이 클래스 파생. 사용자 정의 예외도 이 클래스 파생해야 함."

더 나빠지는 경우

다음 예시에서 os 라이브러리로 현재 작업 디렉토리 가져오려 함. 하지만 내 뚱뚱한 손가락이 오타 냄:

import os
try:
    working_dir = os.getcdw()
    print(working_dir)
except:
    print('error')

os.getcdw는 os 모듈에 없는 함수라 NameError 발생. 실패 대신 except 절이 에러 잡고 'error' 출력, 프로그램 우리 뻔뻔한 오타에도 계속 진행. 안타깝게 이거 Exception 잡는 걸로도 해결 안 됨!

우리가 1단계서 배운 작은 트릭이 우리 모든 문제 해결책 아님. 그럼 뭐를 해야 할까?

다룰 수 있는 것만 잡기

예외 대해 자주 듣는 말: 다룰 수 있는 것만 잡으라. 많은 개발자 예외 직접 다루려 유혹받지만, 종종 예외를 실제로 다룰 수 있는 프로그램 부분으로 전파시키는 게 더 나음.

예: 파일 열고 로드하는 텍스트 에디터 부분, OpenFile 클래스라 하자. 사용자 없는 파일 열 요청 시, 에러 직접 처리하거나 전파 가능.

이 경우 호출자로 전파하는 게 나음. OpenFile은 이 예외가 호출자에게 얼마나 나쁜지 모름. 호출자가 여러 방식으로 상황 처리 가능:

어느 쪽이든 FileNotFoundError 경우 뭐 할지는 OpenFile 클래스 몫 아님.

그럼 예외 항상 전파해야 하나? 아님. OpenFile 클래스서 다룰 수 있는 예외 예: TimeoutError. 몇 번 재시도 해 호출자 귀찮게 안 할 수 있음. 이건 OpenFile이 다룰 수 있는 예외니 잡고 재시도 괜찮음.

결론

어떤 상황에서도 다룰 수 있는 것보다 더 많은 예외 잡지 말아야 함. 담요 같은 except 블록은 버그와 예측 불가능 코드 레시피. 다른 말로: 다룰 수 있는 것만 잡으라.

코드 '다룰 수 있는 것만 잡으라' 마인드로 쓰면 잡아먹기 블록은 모든 규칙 위반. 제발 그만하세요. 연습으로 기존 코드 다시 보며 이 새 지식으로 개선 가능한지 확인해보세요!

python

  1. 파이썬 연산자 마스터하기: 종합 가이드
  2. Python 에러와 내장 예외 마스터하기
  3. Python 사용자 정의 예외 마스터하기: 실전 가이드
  4. Python 현재 날짜와 시간 가져오기: 실전 가이드
  5. Java 다중 예외 처리 마스터: 단일 Catch 블록으로 여러 예외 잡기
  6. CMMS 교육 마스터: 팀 참여 유도와 지식 정착
  7. Python print() 함수 완벽 가이드: 예제와 고급 기법
  8. Python 딕셔너리: 키/값 쌍 추가, 업데이트, 관리 실전 가이드
  9. 파이썬 print() 줄바꿈 없이 출력하기: end 매개변수 & 기타 기법 마스터
  10. 파이썬으로 평균 계산하기: 실전 가이드