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 of object
'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 as list
and Exception
, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With