【问题标题】:Python3, calling super's __init__ from a custom exceptionPython3,从自定义异常调用 super 的 __init__
【发布时间】:2018-09-26 04:22:21
【问题描述】:

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

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

【问题讨论】:

    标签: python python-3.x exception super


    【解决方案1】:

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

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

    class CustomError(Exception):
      def __init__(self, message, status):
          super().__init__(message, status)
          self.message = message
          self.status = status 
    

    这可能看起来有点奇怪,但 Exception 的默认行为 是接受所有传递的参数并将它们存储在 .args 属性作为元组。 Python 的各种其他库和部分 期望所有异常都有 .args 属性,所以如果你跳过这个 步骤,你可能会发现你的新异常表现得不太好 在某些情况下是正确的。为了说明 .args 的使用,请考虑 这个带有内置 RuntimeError 异常的交互式会话,以及 注意 raise 可以使用任意数量的参数 声明:

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

    class AuthException(Exception): 
        def __init__(self, username, user=None): 
            super().__init__(username, user) 
            self.username = username 
            self.user = user 
     
    class UsernameAlreadyExists(AuthException): 
        pass 
     
    class PasswordTooShort(AuthExceptio)
        pass
    
    

    我必须注意,与其通过,不如按照 Luciano Ramalho 的建议在此处添加字符串文档

    让我们看看它的用途

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

    希望对你有帮助

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-30
        • 2021-09-13
        • 2020-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        相关资源
        最近更新 更多