【发布时间】:2014-10-18 17:23:19
【问题描述】:
据我了解,我可以使用 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 不是抽象的,我会得到我期望的标准堆栈跟踪:
Traceback (most recent call last)
File "./email2pdf_classexception", line 21, in <module>
raise ExitCodeException("Oh no!")
__main__.ExitCodeException
我该如何解决这个问题?
【问题讨论】:
-
在 Python3 中你应该使用关键字语法:
class ExitCodeException(Exception, metaclass = abc.ABCMeta):。但是,这不足以解决您的问题。Exception基类使实例化成为可能——没有它,一切都按预期工作。但我想它不能解决你的问题,因为你想从这个基类派生出可抛出的异常。 -
首先,Python3 中定义元类的语法发生了变化。它必须作为关键字参数(称为
metaclass)传递给类定义(参考:docs.python.org/3.3/reference/…)。其次,我一个 ABC 不能有一个不是 ABC 的基类。因此,如果您想让ExitCodeException成为 ABC,则不能将Exception(不是 ABC)作为ExitCodeException的基类。所以,我认为没有一种直接的方法可以让你的代码正常工作。 -
为什么不能实例化基类很重要?如果您不想实例化它,就不要实例化它。这感觉就像尝试用 Python 编写 Java。
-
@BartoszKP,Debanshu Kundu:你们都在评论中给出了相同的答案。把它放在答案中! :)
-
@AndrewFerrier:Python 不是一门严格的语言。有很多你不应该做的事情,Python 不会阻止你去做。谁在尝试实例化您的基本异常?他们为什么这样做?这感觉就像在寻找一个非问题的解决方案。
标签: python exception abstract-class python-3.4 abc