Python: Is it bad form to raise exceptions within __init__?
在
在
当然,要提高的错误类是由您决定的。如果向构造函数传递的参数无效,则最好使用
确实,指示构造函数中错误的唯一正确方法是引发异常。这就是为什么在C++和其他面向对象语言中,已经设计了异常安全的思想,如果在对象的构造函数中抛出异常(不意味着对象的初始化是不完整的),则不调用析构函数。在脚本语言(如Python)中,情况往往不是这样。例如,如果套接字连接()失败,下面的代码会引发AtEdTrError错误:
1 2 3 4 5 6 7 8 9 | 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开发人员避免完全使用析构函数,但这是另一个争论的问题。
我看不出有什么理由认为它的形式不好。
相反,与返回错误代码相反,异常的一个原因是构造函数通常不能返回错误代码。因此,至少在C++语言中,提高异常是唯一的方法来发出错误信号。
标准图书馆说:
1 2 3 4 | >>> f = file("notexisting.txt") Traceback (most recent call last): File"<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: 'notexisting.txt' |
我也不明白为什么它会被认为是不好的形式。
我认为这是内置
在某些情况下,从init中引发错误是不可避免的,但是在init中做太多的工作是一种糟糕的风格。您应该考虑创建一个工厂或伪工厂——一个返回已设置对象的简单类方法。
我同意上述所有观点。
实际上,除了引发异常之外,没有其他方法可以表明在初始化对象时发生了错误。
在大多数程序类中,如果一个类的状态完全依赖于该类的输入,我们可能会期望引发某种类型的valueerror或typeerror。
如果(例如)网络设备不可用或画布对象无法写入,则具有副作用的类(例如,具有网络或图形功能的类)可能会在init中引发错误。这对我来说听起来很明智,因为你经常想尽快了解故障情况。