捕获导入模块引发的本地异常类型

Catching local exception type raised by imported module

我有一个定义通用 class 的主模块,以及一个定义子 class.

的第二个模块

当运行主模块作为脚本时,我想使用来自第二个模块的子class。但是我无法捕获主模块中声明的异常

# a.py
class CustomException(Exception): pass

class A:
    def raise_exception(self):
        raise CustomException()

if __name__ == '__main__':
    import b
    try:
        b.B().raise_exception()
    except CustomException as e:
        print('Caught as CustomException')
    except Exception as e:
        print('Caught as generic Exception.')
        print(type(e))

    # Output:
    # Caught as generic Exception.
    # <class 'a.CustomException'>
# b.py
from a import A

class B(A):
    pass

问题是当第二个模块导入主模块时创建了第二个 CustomException 类型。 [1]

注意捕获异常的 type<class 'a.CustomException'>,而不是 <class 'CustomException'>。为了证明它们确实是不同的类型,以下都是假的:

id(CustomException) == id(type(e))
type(e) == CustomException
isinstance(e, CustomException))

解决方案是不要通过两个不同的路径(本地名称和来自 b.py)导入相同的值 (CustomException)。必须重写脚本以避免循环导入。