问题:Python:在__init__中引发异常是否不好?
在其中引发异常是否被认为是不好的形式__init__
?如果是这样,那么当某些类变量初始化为None
错误类型或类型错误时,可以接受的引发错误的方法是什么?
回答 0
在内部引发异常__init__()
是绝对可以的。在构造函数中没有其他好的方法来指示错误情况,并且标准库中有数百个示例,在这些示例中构建对象会引发异常。
当然,要提出的错误类别由您决定。ValueError
如果向构造函数传递了无效的参数,则最好。
回答 1
确实,在构造函数中指示错误的唯一正确方法是引发异常。这就是为什么在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开发人员完全避免使用析构函数,但这是另一个参数的问题。
回答 2
我看不出任何形式的错误。
相反,与返回错误代码相反,已知异常处理得很好的原因之一是,构造函数通常无法返回错误代码。因此,至少在像C ++这样的语言中,引发异常是发出错误的唯一途径。
回答 3
标准库说:
>>> 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'
我也没有真正看到任何理由将其视为错误的形式。
回答 4
我应该认为这是内置ValueError
异常的完美案例。
回答 5
我同意以上所有观点。
除了引发异常外,实际上没有其他方法可以表明对象的初始化出错。
在大多数程序类中,类的状态完全取决于该类的输入,我们可能期望引发某种ValueError或TypeError。
如果(例如)网络设备不可用或无法写入画布对象,则具有副作用的类(例如,进行网络或图形处理的类)可能会在初始化中引发错误。这对我来说听起来很合理,因为您通常希望尽快了解故障情况。
回答 6
在某些情况下,不可避免地要从init引发错误,但是init太多的工作是不好的风格。您应该考虑建立工厂或伪工厂-一种简单的类方法,该方法返回设置的对象。