python - 创建一个继承自 Exception 的抽象基类
问题描述
我正在尝试为我的应用程序中引发的异常创建一个自定义基类。我想让它成为一个不能直接实例化的抽象类(使用 abc 模块),以强迫自己为不同类型的错误情况定义更具体的具体子类。
我可以定义一个继承自自定义具体类的抽象类。然而,令我惊讶的是,如果我让抽象类(直接或间接)从 Exception 继承,它可以再次直接实例化,从而破坏了首先使其抽象的目的。
我想了解这里发生了什么,以便我可以使我的自定义异常类抽象为真实而不是直接可实例化。
我尝试了将自定义异常类声明为抽象的不同变体,包括使用metaclass=abc.ABCMeta
语法以及从abc.ABC
. 不管它被声明为抽象的方式如何,只要我让它继承自Exception
.
对我来说相关的 Python 版本是 3.5、3.6 和 3.7。我已经在 Python 3.5.2 (Ubuntu 16.04) 和 3.6.8 (Ubuntu 18.04) 上测试了以下代码。
以下似乎按预期工作:由于抽象方法 ( TypeError: Can't instantiate abstract class AppException with abstract methods abs_method
),实例化 AppException 失败。
请注意,尽管这些类被称为*Exception
,但它们(尚未)继承自真正的内置 Exception 类。
import abc
class BaseException():
pass
class AppException(BaseException, abc.ABC):
@abc.abstractmethod
def abs_method(self):
pass
class ConcreteException(AppException):
def abs_method(self):
return "concrete method"
# BaseException can be instantiated just fine
a = BaseException()
# ConcreteException can be instantiated just fine
c = ConcreteException()
# It shouldn't be possible to instantiate AppException directly,
# so this line should raise a TypeError
b = AppException()
当我将 BaseException 的定义更改为从实际Exception
类继承时:
class BaseException(Exception):
pass
然后TypeError
消失了,所以这次 AppException 的实例化确实有效。AppException
不再表现为抽象类,即使在我的理解中,它应该。
这是实际的代码,目前作为 PR 草案一直停留在我弄清楚发生了什么之前。
解决方案
这在此SO 讨论的前面已经介绍过。
没有明显的解决方案,但一种可能的解决方法(来自上面的 SO 讨论)是__init__
在“抽象”扩展类中添加一个方法,以防止它被直接实例化。
推荐阅读
- google-apps-script - 共享文件后 onSelectionChange 损坏
- node.js - 如何通过 ID 获取 json 数组中的数据?
- php - 如何在类函数的包含文件中声明 php supper global const?
- javascript - ASP.NET MVC 上的客户端验证
- android - Android工作室错误没有找到'app'的变体
- android - Recyclerview/cardview 替换默认弹出标题项不起作用 kotlin android
- neo4j - 需要在每个页面上显示用户的单个帖子 Neo4j Cypher
- c - 通知调用函数 C 中的运行时错误
- android - React 本机发布版本构建失败并出现 D8:程序类型已存在:com.reactnativecommunity.webview.BuildConfig
- django - form_valid 导致 TypeError: quote_from_bytes() 预期字节