与异常相关的Python类继承

与异常相关的Python类继承,python,inheritance,exception,Python,Inheritance,Exception,我有课 class IncorrectOfferDetailsOfferException(Exception): def __init__(self, offer): self.offerName = offer[0] self.offerType = offer[1] self.message = "Offer \"" + self.offerName + "\" could not be completed. It appears t

我有课

class IncorrectOfferDetailsOfferException(Exception):
    def __init__(self, offer):
        self.offerName = offer[0]
        self.offerType = offer[1]
        self.message = "Offer \"" + self.offerName + "\" could not be completed. It appears to be of type \"" + self.offerType + "\", but this may be what is wrong and causing the exception."
        super(IncorrectOfferDetailsOfferException, self).__init__(self.message)
我想写一个更一般的类来扩展它

class BadOfferException(Exception):
    def __init__(self, offer):
        self.offerName = offer[0]
        self.offerType = offer[1]
        self.message = "Offer \"" + self.offerName + "\" caused a problem."

如何将这两者联系起来,以删除冗余代码,并用更具体的文本覆盖更一般的消息文本?你知道,类继承。我在理解如何正确使用
super
时遇到了很多困难。

如何使用子类型覆盖的方法:

class BadOfferException(Exception):
    def __init__(self, offer):
        self.offerName = offer[0]
        self.offerType = offer[1]
        self.message = self._construct_message()
        super(BadOfferException, self).__init__(self.message)

    def _construct_message(self):
        return 'Offer "{}" caused a problem'.format(self.offerName)


class IncorrectOfferDetailsOfferException(BadOfferException):
    def _construct_message(self):
        return 'Offer "{}" could not be completed. It appears to be of type "{}", but this may be what is wrong and causing the exception.'.format(self.offerName, self.offerType)

然后,当您提出不正确的异常时,它只是“起作用”

首先,创建子类的方法是通过顶部的基类列表:

class BadOfferException(Exception):
    # etc.

class IncorrectOfferDetailsOfferException(BadOfferException):
    # etc.
我刚刚用
BadOfferException
替换了
Exception
。(我们不需要两者,因为
BadOfferException
已经是
Exception
的子类)并且您必须先声明超类,然后声明子类,所以我改变了顺序


现在,您希望使超类的实现更通用一些,这样子类就可以只覆盖它关心的部分。唯一不同的是信息,对吗?因此,允许将其传入:

class BadOfferException(Exception):
    def __init__(self, offer, message=None):
        self.offerName = offer[0]
        self.offerType = offer[1]
        if message is None:
            message = "Offer \"" + self.offerName + "\" caused a problem."
        self.message = message
现在,您只需通过
super
即可通过这些功能。这意味着我们不能使用
offerName
offerType
,因为它们尚未定义,但这不是问题:

class IncorrectOfferDetailsOfferException(BadOfferException):
    def __init__(self, offer):
        message = "Offer \"" + offer[0] + "\" could not be completed. It appears to be of type \"" + offer[1] + "\", but this may be what is wrong and causing the exception."
        super(IncorrectOfferDetailsOfferException, self).__init__(offer, message)
这就是你需要做的



但是,当我们进行此操作时,您可能希望将
badoferexception
变成
Exception
的一个更好的子类。人们希望能够在
异常
实例上看到
参数
,这不是强制性的;你可以不使用它,它只是一个空的元组,但它很好。您可以通过调用
super(BadOfferException,self)。\uuuu init\uuuu(offer)

首先,对于继承,关键问题不是如何共享代码,而是一个是否是另一个的子类型。如果除BadOfferException:之外执行了
,则是否应捕获异常的
不正确的OfferDetails
?如果是,则将
IncorrectOfferDetailsOfferException
作为
BadOfferException
的子类。如果没有,还有其他方法可以共享代码——mixin类、类装饰器、帮助函数……因此,请先确定这些,然后我们可以帮助您完成下一步。@abarnert incorrectofferdeailsofferexception应该是BadOfferException的子类。我不知道如何做到这一点,用前者来召唤后者的专门版本。我喜欢这个。看起来很聪明,真的完成了任务。非常感谢。我明白这一点。这是一个干净的解决方案。@SmallBlueGarbageCollector我认为salparadise的对于许多用例来说更干净、更强大。这是最简单的解决方案,但不一定是最好的。