据我所知,我可以使用Python中的abc模块来创建无法实例化的抽象类(以及其他不错的属性)。我尝试使用它来创建Exception
类的层次结构来表示我的应用程序的各种退出代码,但我仍然可以实例化我的基类,即使我不想要它发生。这里有一些代码可以证明这个问题:
#!/usr/bin/env python3
import abc
class ExitCodeException(Exception):
__metaclass__ = abc.ABCMeta
def __init__(self, message):
super().__init__()
self._message = message
@abc.abstractmethod
def getExitCode(self):
"""Return the exit code for this exception"""
return
class FatalException(ExitCodeException):
def getExitCode(self):
return 1
raise ExitCodeException("Oh no!")
我期待我的程序退出,但有一个例外,即ExitCodeException
无法实例化,而是我得到标准的堆栈跟踪,如果ExitCodeException
没有&我#39;摘要:
Traceback (most recent call last)
File "./email2pdf_classexception", line 21, in <module>
raise ExitCodeException("Oh no!")
__main__.ExitCodeException
我该如何解决这个问题?
答案 0 :(得分:2)
正如上面@BartoszKP和@Debanshu Kundu的评论中所讨论的那样,具体的超类Exception
似乎是导致此问题的原因。因此,我提出了一个稍微不同的模式,似乎有效(据我所知,这是Python 2中较老式的模式,但似乎仍然有效):
#!/usr/bin/env python3
class ExitCodeException(Exception):
def __new__(cls, *args, **kwargs):
if cls is ExitCodeException:
raise NotImplementedError("Base class may not be instantiated")
return Exception.__new__(cls, *args, **kwargs)
def __init__(self, message):
super().__init__()
self._message = message
def getExitCode(self):
"""Return the exit code for this exception"""
return
class FatalException(ExitCodeException):
def getExitCode(self):
return 1
raise FatalException("Oh no!")
这是按预期工作的;如果我将代码更改为直接实例化ExitCodeException
,则会失败。