我想在Python中声明用户定义的异常的层次结构。但是,我希望我的顶级用户定义类(TransactionException
)是抽象的。也就是说,我打算TransactionException
指定其子类需要定义的方法。但是,TransactionException
永远不应该被实例化或提升。
我有以下代码:
from abc import ABCMeta, abstractmethod
class TransactionException(Exception):
__metaclass__ = ABCMeta
@abstractmethod
def displayErrorMessage(self):
pass
但是,上面的代码允许我实例化TransactionException
...
a = TransactionException()
在这种情况下,a
没有意义,应该绘制一个例外。以下代码删除了TransactionException
是Exception
...
from abc import ABCMeta, abstractmethod
class TransactionException():
__metaclass__ = ABCMeta
@abstractmethod
def displayErrorMessage(self):
pass
此代码正确禁止实例化,但现在我无法引发TransactionException
的子类,因为它不再是Exception
。
可以在Python中定义抽象异常吗?如果是这样,怎么样?如果没有,为什么不呢?
注意:我使用的是Python 2.7,但很乐意接受Python 2.x或Python 3.x的答案。
答案 0 :(得分:3)
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 :(得分:3)
Alex Martelli here对这个主题有一个很好的答案。从本质上讲,它描述了各种基类(__init__
,object
和我假设list
)的对象初始值设定项(Exception
)在抽象方法中的表现在场。
当抽象类继承自object
时(默认情况下,如果没有给出其他基类),它的__init__
方法设置为object
的方法,在检查所有抽象方法是否已实施时执行繁重的工作。
如果抽象类继承自不同的基类,它将获得该类“__init__
方法”。其他类,例如list
和Exception
,似乎不检查抽象方法实现,这就是允许实例化它们的原因。
另一个答案为此提供了建议的解决方法。当然,你拥有的另一个选择就是接受抽象类是可实例化的,并试图阻止它。
答案 2 :(得分:0)
我对抽象异常类的实现
class TransactionException(Exception):
def __init__(self):
self._check_abstract_initialization(self)
@staticmethod
def _check_abstract_initialization(self):
if type(self) == TransactionException:
raise NotImplementedError("TransactionException should not be instantiated directly")
class AnotherException(TransactionException):
pass
TransactionException() # NotImplementedError: TransactionException should not be instantiated directly
AnotherException # passes