Python3,从自定义异常中调用super的__init__

cdx*_*530 5 python exception super python-3.x

我已经在 python 3 中创建了自定义异常,并且所有代码都工作得很好。但有一件事我无法理解,为什么我需要将消息发送到 Exception 类的__init__()以及当我尝试打印异常时它如何将自定义异常转换为该字符串消息因为 Exception 甚至 BaseException 中的代码没有做太多事情。

不太明白为什么从自定义异常中调用super().__init__()

Mas*_*use 5

比兹利、大卫. Python 食谱(第 578 页)。奥莱利媒体。

\n
\n

如果要定义一个新的异常来覆盖Exception 的init () 方法,请确保始终调用 Exception。init () 以及所有传递的参数。例如:\n:

\n
\n
class CustomError(Exception):\n  def __init__(self, message, status):\n      super().__init__(message, status)\n      self.message = message\n      self.status = status \n
Run Code Online (Sandbox Code Playgroud)\n
\n

这可能看起来有点奇怪,但 Exception\nis 的默认行为是接受传递的所有参数并将它们作为元组存储在 \xe2\x80\x8b .args\nattribute 中。Python 的各种其他库和部分\n期望所有异常都具有 .args 属性,因此,如果您跳过此\n步骤,您可能会发现新异常在某些上下文中\n\xe2\x80\x99 的行为不正确。为了说明 .args 的用法,请考虑这个带有内置 RuntimeError 异常的交互式会话,并注意如何在 raise 语句中使用任意数量的参数:

\n
\n

菲利普斯,达斯蒂。Python 3 面向对象编程:在 Python 3.8 第三版中使用面向对象设计模式构建健壮且可维护的软件(第 119 页)

\n
class AuthException(Exception): \n    def __init__(self, username, user=None): \n        super().__init__(username, user) \n        self.username = username \n        self.user = user \n \nclass UsernameAlreadyExists(AuthException): \n    pass \n \nclass PasswordTooShort(AuthExceptio)\n    pass\n\n
Run Code Online (Sandbox Code Playgroud)\n

我必须注意,最好按照 Luciano Ramalho 的建议在此处添加字符串文档,而不是通过

\n

那么让我们看看它的用途

\n
\nclass Authenticator:\n    def __init__(self):\n        """Construct an authenticator to manage\n        users logging in and out."""\n        self.users = {}\n def add_user(self, username, password):\n        if username in self.users:\n            raise UsernameAlreadyExists(username)\n        if len(password) < 6:\n            raise PasswordTooShort(username)\n        self.users[username] = User(username, password)\n
Run Code Online (Sandbox Code Playgroud)\n

希望这可以帮助

\n


blh*_*ing 3

这样您的自定义异常就可以从与 BaseException对象相同的实例属性开始,包括value存储异常消息的属性,某些其他方法需要该属性__str__,例如 ,它允许将异常对象转换为直接串。如果需要,您可以跳过super().__init__子类中的调用__init__,而是自行初始化所有必要的属性,但这样您就无法利用类继承的主要优点之一。super().__init__除非您有非常具体的原因不重用任何父类的实例属性,否则始终调用。