프로그래밍백엔드 개발자

파이썬의 예외 처리 메커니즘에 대해 설명하십시오. try/except/finally 블록은 어떻게 작동하며, raise는 무엇을 위해 필요한지, 자주 발생하는 함정은 무엇인지 알려주세요.

Hintsage AI 어시스턴트로 면접 통과

답변

파이썬에서는 예외 처리가 try/except/else/finally 구문과 raise 연산자를 통해 구현됩니다.

try는 보호되는 코드 블록을 정의합니다. 그 안에서 예외가 발생하면, 제어는 가장 가까운 적절한 except 블록으로 전달됩니다. 예외가 없으면 else 블록이 실행됩니다. finally 블록은 예외 여부와 관계없이 항상 실행됩니다 (예: 리소스 해제용).

raise 연산자는 명시적으로 예외를 발생시키거나 현재의 예외를 다시 발생시킵니다 (except 블록에서 타입을 지정하지 않는 경우).

예시:

try: x = 1 / 0 except ZeroDivisionError as e: print(f"오류: {e}") else: print("오류가 없었습니다") finally: print("항상 실행됩니다")

출력:

오류: division by zero
항상 실행됩니다

세부 사항:

  • 중첩된 예외 처리기에서는 except의 순서가 중요합니다: 구체적인 유형에서 일반적인 유형으로 (그렇지 않으면 구체적인 것이 처리되지 않습니다).
  • finally 블록은 예외가 재발생하는 것을 방지할 수 없습니다 (finally 내부에 raise를 삽입하면 가장 "최근"의 오류가 적용됩니다).

난감한 질문

질문: "try 블록과 finally 블록에서 각각 다른 예외를 raise 하면 어떻게 될까요?"

답변: finally에서의 예외가 try에서의 예외를 "가린다": 외부로 나오는 것은 finally에서 발생한 것입니다.

def foo(): try: raise ValueError("try에서") finally: raise IndexError("finally에서") try: foo() except Exception as e: print(repr(e)) # 출력: IndexError('finally에서')

주제에 대한 세부 사항을 모르는 것으로 인한 실제 오류의 예


이야기

ETL 프로세스에서 finally 블록에서 조건 없이 데이터베이스 연결을 닫았지만, finally에서 예외가 발생할 수 있다는 것을 잊어버렸습니다 (예: 이미 연결이 닫혀 있을 경우). 결과적으로 finally에서의 "숨겨진" 예외가 기본 코드에서의 예외를 완전히 흡수하여 디버깅을 복잡하게 만들었습니다.


이야기

여러 개의 except 체인을 사용했지만, 일반적인 except Exception 위에 구체적인 것을 두었습니다. 결과적으로 모든 특정 except가 "죽은" 상태로 남아, 저수준 예외가 별도로 캡처되지 않았으므로 특정 오류 처리가 어려웠습니다.


이야기

웹 서비스에서 except 블록에서 예외를 "raise"로 이어주지 않고 오류를 로깅했지만 실행이 계속되게 했습니다. 그 결과 실제 오류가 "사라지고", 프로그램은 잘못된 상태로 계속 실행되었습니다.