2013-11-20 3 views
4

파이썬에서 사용자 정의 예외의 계층 구조를 선언하고 싶습니다. 그러나 최상위 사용자 정의 클래스 (TransactionException)를 추상화하고 싶습니다. 즉, TransactionException은 서브 클래스가 정의해야하는 메소드를 지정하려고합니다. 그러나 TransactionException을 인스턴스화하거나 제기해서는 안됩니다.파이썬에서 추상 예외를 선언 할 수 있습니까?

나는 다음과 같은 코드가 있습니다

from abc import ABCMeta, abstractmethod 

class TransactionException(Exception): 
    __metaclass__ = ABCMeta 

    @abstractmethod 
    def displayErrorMessage(self): 
     pass 

그러나, 위의 코드 나 TransactionException를 인스턴스화 할 수 있습니다 ... a 의미가이 경우

a = TransactionException() 

을 대신 예외를 그린다 . 다음 코드는 TransactionExceptionException의 서브 클래스라는 사실 ...

from abc import ABCMeta, abstractmethod 

class TransactionException(): 
    __metaclass__ = ABCMeta 

    @abstractmethod 
    def displayErrorMessage(self): 
     pass 

이 코드가 제대로 인스턴스를 금지하고 있지만 어떤 이상 Exception 아니기 때문에 지금은 TransactionException의 서브 클래스를 발생시킬 수 없습니다를 제거합니다.

파이썬에서 추상 예외를 정의 할 수 있습니까? 그렇다면 어떻게? 그렇지 않다면 왜 안 되겠습니까?

참고 : 저는 Python 2.7을 사용하고 있지만, Python 2.x 또는 Python 3.x에 대한 답변을 기꺼이 수락 할 것입니다.

답변

2

Alex Martelli의이 질문에 대한 답변은 here입니다. 본질적으로, 다양한 기본 클래스 (object, list 및 전 가정, Exception)의 객체 이니셜 라이저 (__init__)가 추상 메소드가있을 때 어떻게 작동 하는지를 설명합니다. 추상 클래스는 (다른 기본 클래스도 주어지지 않는다면 기본이되는) object 상속되면

그것은 __init__있어서 모든 추상 메소드 경우 검사에 큰 리프트를 수행 object 년대의 값으로 설정되어있어 구현되었습니다.

추상 클래스가 다른 기본 클래스에서 상속을받는 경우 해당 클래스는 '__init__ 메소드가됩니다. listException과 같은 다른 클래스는 추상화 구현을 검사하지 않으므로이를 인스턴스화하는 것이 허용됩니다.

다른 답변은 이에 대한 제안 된 해결책을 제공합니다. 물론, 또 다른 옵션은 추상 클래스가 인스턴스화 될 수 있다는 것을 받아 들여 낙담시키려는 것입니다.

4
class TransactionException(Exception): 

    def __init__(self, *args, **kwargs): 
     raise NotImplementedError('you should not be raising this') 


class EverythingLostException(TransactionException): 

    def __init__(self, msg): 
     super(TransactionException, self).__init__(msg) 


try: 
    raise EverythingLostException('we are doomed!') 
except TransactionException: 
    print 'check' 

try: 
    raise TransactionException('we are doomed!') 
except TransactionException: 
    print 'oops' 
+1

엄밀히 말하면 여전히'TransactionException'을 인스턴스화 할 수 있습니다. 단지 초기화 할 수 없습니다 ('exc = TransactionException .__ new __ (TransactionException)'). 그러나 이것은 OP가 원하는 것의 정신에있을 것입니다. – chepner

관련 문제