Python: 在__init__中抛出异常是否不合适?

169 投票
8 回答
83245 浏览
提问于 2025-04-15 14:44

__init__方法里抛出异常算不算不好的做法呢?如果算,那在某些类变量被初始化为None或者类型不正确时,应该用什么方法来报错呢?

8 个回答

11

我觉得这样做没有什么不好的地方。

相反,异常处理有一个很好的特点,就是它比返回错误代码要好。因为错误代码通常不能在构造函数里返回。所以在像C++这样的编程语言中,抛出异常是唯一能用来表示错误的方式。

38

确实,在构造函数中表示错误的唯一正确方式就是抛出异常。这就是为什么在C++和其他一些设计时考虑了异常安全的面向对象语言中,如果对象的构造函数抛出异常,析构函数就不会被调用(这意味着对象的初始化没有完成)。而在一些脚本语言中,比如Python,情况往往不是这样。例如,下面的代码如果socket.connect()失败,就会抛出一个AttributeError:

class NetworkInterface:
    def __init__(self, address)
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect(address)
        self.stream = self.socket.makefile()

    def __del__(self)
        self.stream.close()
        self.socket.close()

原因是,在连接尝试失败后,未完成对象的析构函数会被调用,而此时流属性还没有被初始化。你不应该避免在构造函数中抛出异常,我只是想说在Python中写出完全安全的异常处理代码是比较困难的。一些Python开发者甚至完全不使用析构函数,但这又是另一个话题了。

215

__init__()这个初始化方法里抛出异常是完全可以的。这是表示初始化过程中出现错误的好方法,而且在标准库中,有很多例子都是在初始化对象时抛出异常。

至于你要抛出什么样的错误,这个由你来决定。如果初始化时传入了无效的参数,抛出ValueError是最合适的选择。

撰写回答