可继承的自定义异常在Python中

2 投票
3 回答
637 浏览
提问于 2025-04-15 17:08

我想为我的类创建一些自定义的异常。现在我在想,怎么才能让这些异常类在派生类中也能用。教程里展示了怎么创建异常类,所以我就按照那样做了:

我创建了一个叫 baseclass.py 的文件:

class Error(Exception):
    """Base class for exceptions in BaseClass"""
    pass

class SomeError(Error):
    """Exection for some error"""
    def __init__(self, msg):
        self.msg = msg

class OtherError(Error):
    """Exection for some error"""
    def __init__(self, msg):
        self.msg = msg

class BaseClass():
    """Base test class for testing exceptions"""

    def dosomething(self):
        raise SomeError, "Got an error doing something"

然后我又创建了一个叫 derivedclass.py 的文件:

from baseclass import BaseClass,SomeError,OtherError

class DerivedClass(BaseClass):

    def doother(self):
        """Do other thing"""
        raise OtherError, "Error doing other"

接着我写了一个测试,使用了 DerivedClass:

#!/usr/bin/python
from derivedclass import DerivedClass,SomeError,OtherError

"""Test from within module"""
x = DerivedClass()
try:
    x.dosomething() 
except SomeError:
    print "I got some error ok"

try:
    x.doother()
except OtherError:
    print "I got other error ok"

从上面可以看到,我把异常类从基类导入到了派生类中,然后又从派生类导入到程序里。

这样做似乎可以,但看起来不太优雅。我担心在派生类模块里必须为所有异常类都做一次导入,这样在创建新的派生类时,很容易忘记导入某个异常类。如果用户在使用这个派生类时遇到这个问题,就会出错。

有没有更好的办法呢?

谢谢!

-Mark

3 个回答

0

如果用户通过名称导入你的错误类,他们会在导入语句执行时立刻发现问题:

ImportError: cannot import name FrotzError
File "enduser.py", line 7, in <module>
  from ptcmark.derivedclass import FrotzError

当然,你会在文档中说明他们应该从哪里获取这些异常类,所以他们只需查阅文档,然后修改代码来做正确的事情:

from ptcmark.errors import FrotzError
0

自定义的异常需要在所有使用它的模块中导入。

另外,derivedclass.py 文件中有一个错误。

Wrong (because of the way its imported)
raise baseclass.OtherError, "Error doing other"

Fixed
raise OtherError, "Error doing other"
0

你看,我把异常类从基类导入到了派生类,然后又从派生类导入到了程序里。

其实,你不能也不需要从类里导入异常(或者其他东西)。你是从模块里导入东西,通常也是导入到模块里。

(通常是这样,因为你可以在任何地方写导入语句,但这样做并不推荐)

这样做似乎可以,但不太优雅。我担心在派生类的模块里得确保导入所有的异常类。创建新派生类的时候,可能会忘记导入其中一个。这样的话,使用这个派生类的用户就会遇到错误。

其实,派生类的模块并不需要导入所有基类的异常。如果你想让其他代码更容易知道从哪里导入异常,可以把所有异常放在一个单独的模块里,命名为“errors”或者“exceptions”,这是Python中常见的做法。

另外,如果你发现管理异常的命名空间很麻烦,可能是因为你对异常的分类太细了,实际上可以减少一些异常类。

撰写回答