I would like to declare a hierarchy of user-defined exceptions in Python. However, I would like my top-level user-defined class (TransactionException
) to be abstract. That is, I intend TransactionException
to specify methods that its subclasses are required to define. However, TransactionException
should never be instantiated or raised.
I have the following code:
from abc import ABCMeta, abstractmethod
class TransactionException(Exception):
__metaclass__ = ABCMeta
@abstractmethod
def displayErrorMessage(self):
pass
However, the above code allows me to instantiate TransactionException
...
a = TransactionException()
In this case a
is meaningless, and should instead draw an exception. The following code removes the fact that TransactionException
is a subclass of Exception
...
from abc import ABCMeta, abstractmethod
class TransactionException():
__metaclass__ = ABCMeta
@abstractmethod
def displayErrorMessage(self):
pass
This code properly prohibits instantiation but now I cannot raise a subclass of TransactionException
because it's not an Exception
any longer.
Can one define an abstract exception in Python? If so, how? If not, why not?
NOTE: I'm using Python 2.7, but will happily accept an answer for Python 2.x or Python 3.x.
There's a great answer on this topic by Alex Martelli here. In essence, it comes down how the object initializers (
__init__
) of the various base classes (object
,list
, and, I presume,Exception
) behave when abstract methods are present.When an abstract class inherits from
object
(which is the default, if no other base class is given), it's__init__
method is set to that ofobject
's, which performs the heavy-lifting in checking if all abstract methods have been implemented.If the abstract class inherits from a different base class, it will get that class'
__init__
method. Other classes, such aslist
andException
, it seems, do not check for abstract method implementation, which is why instantiating them is allowed.The other answer provides a suggested workaround for this. Of course, another option that you have is simply to accept that the abstract class will be instantiable, and try to discourage it.