NotImplementedError는 파이썬의 내장 예외로, RuntimeError에서 파생된 예외입니다. 주로 사용자가 정의한 기반 클래스(부모 클래스)에서, 서브클래스(자식 클래스)가 반드시 구현해야 하는 메서드나 동작을 표시할 때 사용됩니다. 이는 다른 언어의 인터페이스(interface) 개념을 흉내 내는 역할을 합니다.
즉, 기반 클래스에서 추상 메서드처럼 동작해야 하는 메서드가 호출되었지만 아직 서브클래스에서 오버라이드되지 않았다면, NotImplementedError를 발생시켜 개발자에게 구현이 필요하다는 사실을 알려주는 것입니다.
NotImplementedError 발생 및 처리 예제
아래 예제는 기반 클래스 Super의 example 프로퍼티가 NotImplementedError를 발생시키고, 이를 try-except 블록으로 잡아내는 과정을 보여줍니다.
import sys
class Super(object):
@property
def example(self):
raise NotImplementedError("Subclasses should implement this!")
s = Super()
try:
print(s.example)
except NotImplementedError as e:
print(e) # 예외 메시지 출력
print(type(e).__name__) # 예외 클래스 이름 출력
실행 결과
Subclasses should implement this!
NotImplementedError
코드 설명
Super클래스의example메서드는 실제 구현 없이NotImplementedError만 발생시킵니다.- 인스턴스
s에서s.example에 접근하는 순간 예외가 발생합니다. except NotImplementedError as e구문으로 해당 예외를 정확하게 잡아낼 수 있습니다.- 발생한 예외 객체에서는 메시지(
e)와 예외 타입(type(e).__name__)을 확인할 수 있습니다.
모든 예외를 포괄적으로 잡는 방법
예외의 종류와 관계없이 모든 예외를 처리하려면 Exception을 사용할 수 있습니다.
try:
print(s.example)
except Exception as e:
print(e)
print(type(e))
다만 Exception으로 넓게 잡으면 의도하지 않은 버그까지 숨겨질 수 있으므로, 가능하면 NotImplementedError처럼 구체적인 예외 타입을 지정하는 것이 좋습니다.
참고: abc 모듈을 활용한 더 나은 방법
실무에서는 인터페이스 역할을 하는 기반 클래스를 만들 때 abc(Abstract Base Classes) 모듈을 사용하는 것이 더 권장됩니다.
from abc import ABC, abstractmethod
class Super(ABC):
@abstractmethod
def example(self):
pass
class Sub(Super):
def example(self):
return "구현된 메서드"
# 추상 메서드를 구현하지 않으면 인스턴스 생성 시점에 TypeError 발생
s = Sub()
print(s.example()) # 구현된 메서드
@abstractmethod 데코레이터를 사용하면 서브클래스가 메서드를 구현하지 않은 채 인스턴스를 생성하려 할 때 즉시 오류가 발생합니다. 따라서 런타임 도중에 문제를 발견하는 것보다 훨씬 안전하게 코드를 작성할 수 있습니다.
정리
NotImplementedError는RuntimeError의 하위 예외로, 서브클래스에서 반드시 구현해야 할 메서드를 표시하는 데 사용됩니다.try-except NotImplementedError구문으로 명확하게 잡아 처리할 수 있습니다.- 더 견고한 설계를 위해서는
abc모듈의 추상 메서드를 활용하는 것이 좋습니다.