在其中引发异常是否被认为是不好的形式__init__
?如果是这样,那么当某些类变量初始化为None
错误类型或类型错误时,可以接受的引发错误的方法是什么?
在其中引发异常是否被认为是不好的形式__init__
?如果是这样,那么当某些类变量初始化为None
错误类型或类型错误时,可以接受的引发错误的方法是什么?
Answers:
在内部引发异常__init__()
是绝对可以的。在构造函数中没有其他好的方法来指示错误情况,并且标准库中有数百个示例,在这些示例中构建对象会引发异常。
当然,要提出的错误类别由您决定。ValueError
如果向构造函数传递了无效的参数,则最好。
ValueError
和TypeError
。
__init__
不是构造函数,而是它的初始化器。您可能需要编辑该行没有其他好的方法来指示构造函数中的错误情况,..
确实,在构造函数中指示错误的唯一正确方法是引发异常。这就是为什么在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开发人员完全避免使用析构函数,但这是另一个争论的问题。
__del__
因为它写得不好。如果this->p_socket->close()
在C ++中使用析构函数,则会遇到完全相同的问题。在C ++中,您不会这样做-让成员对象销毁自己。在python中做同样的事情。
我同意以上所有观点。
除了引发异常外,实际上没有其他方法可以表明对象的初始化出错。
在大多数程序类中,类的状态完全取决于该类的输入,我们可能期望引发某种ValueError或TypeError。
如果(例如)网络设备不可用或无法写入画布对象,则具有副作用的类(例如,进行网络或图形处理的类)可能会在初始化中引发错误。这对我来说听起来很合理,因为您通常希望尽快了解故障情况。