【问题标题】:Good way of catching custom 'indirect' exceptions捕获自定义“间接”异常的好方法
【发布时间】:2020-05-18 16:01:02
【问题描述】:

我正在开发一个 python 应用程序,并且有一个特定的场景让我对处理不同模块中定义的自定义异常感到有些困惑。考虑以下情况:

有模块A.pyB.pyC.pyA.py 定义了一个自定义异常并在出现错误时引发它。 B.py 导入 A.py 并运行其危险功能。稍后,C.py 将导入 B.py 并执行其方法。表示如下:

A.py -> 做一些简单的事情,但很容易引发自定义异常。

class CustomException(Exception):
    pass

def dangerous_function():
    ...
    raise CustomException('Exception occurred')

B.py -> 有很多方法使用模块 A 中的危险函数。

import A

class ModuleB:
    def __init__(self):
        pass

    def run_stuff(self):
        ...
        A.dangerous_function() # throws CustomException

    def run_more_stuff(self):
        ...
        A.dangerous_function() # throws CustomException
        ...

    ...

C.py -> 实例化模块B 并运行其方法。

from A import CustomException # <--
from B import ModuleB

def do_stuff():
    m = ModuleB()

    try:
        m.run_stuff()
    except CustomException as e:
        print(f'Custom error occurred: {e}')

假设模块A 不应该对模块C 可见,是否可以导入它来获取自定义异常?有没有更好的方法?

【问题讨论】:

  • 我想说唯一的问题是如果执行 A.py 的全部内容会非常昂贵,在这种情况下,您可能希望将异常分解到一个单独的模块中。
  • 只有第一个导入会执行A.py:之后模块被缓存为sys.modules['A'],后续导入只是在那里查找。无论如何都必须加载A 才能引发异常。但是,为异常类提供一个单独的模块确实使它们更容易找到。 (参见 Danjou 指南中的“组织”。)

标签: python exception module


【解决方案1】:

C 不需要知道AB 可以做from A import CustomException,然后课程将以B.CustomException 提供。然后C可以从B导入:

from B import ModuleB, CustomException

但是,如果您根本不希望 C 依赖于自定义异常类,则可以让 B 捕获异常并引发 B 定义的异常。 (您可以使用raise from 使原始异常也可用于调试输出。)

请参阅https://julien.danjou.info/python-exceptions-guide/ 包装部分了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多