Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:在_init__中引发异常是一种糟糕的形式吗?_Python_Exception - Fatal编程技术网

Python:在_init__中引发异常是一种糟糕的形式吗?

Python:在_init__中引发异常是一种糟糕的形式吗?,python,exception,Python,Exception,在\uuuu init\uuuu中引发异常是否被认为是不好的形式?如果是这样,那么当某些类变量被初始化为None或类型不正确时,抛出错误的公认方法是什么?我认为这是内置ValueError异常的最佳情况。标准库说: >>> f = file("notexisting.txt") Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno

\uuuu init\uuuu
中引发异常是否被认为是不好的形式?如果是这样,那么当某些类变量被初始化为
None
或类型不正确时,抛出错误的公认方法是什么?

我认为这是内置
ValueError
异常的最佳情况。

标准库说:

>>> 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'
>f=file(“notexisting.txt”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
IOError:[Errno 2]没有这样的文件或目录:“notexisting.txt”

另外,我真的看不出有什么理由认为它是不好的形式。

\uuuu init\uuuu()
中引发异常是绝对好的。在构造函数中没有其他好的方法来指示错误条件,在标准库中有数百个示例,其中构建对象可能引发异常


当然,要提出的错误类别取决于您
ValueError
如果构造函数被传递了一个无效的参数,那么它是最好的。

我看不出有任何理由认为它是错误的形式


相反,与返回错误代码相反,异常表现出色的原因之一是构造函数通常不能返回错误代码。所以至少在C++语言中,提高异常是唯一的错误信号。

< P>我同意以上所有。 除了引发异常之外,没有其他方法可以表明在初始化对象时出错

在大多数程序类中,一个类的状态完全依赖于该类的输入,我们可能期望出现某种ValueError或TypeError


如果(例如)网络设备不可用或画布对象无法写入,则具有副作用的类(例如,具有网络或图形功能的类)可能会在init中引发错误。对我来说,这听起来很合理,因为您经常希望尽快了解故障情况

在构造函数中指出错误的唯一正确方法是引发异常,这是事实。这就是为什么在C++中以及其他设计为异常安全的面向对象语言时,如果在对象的构造函数中抛出异常(不意味着对象的初始化不完整),则不调用析构函数。在脚本语言(如Python)中通常不是这样。例如,如果socket.connect()失败,以下代码将抛出AttributeError:


原因是,未完成对象的析构函数是在连接尝试失败后、流属性初始化之前调用的。您不应该避免从构造函数抛出异常,我只是说用Python编写完全异常安全的代码是很困难的。一些Python开发人员完全避免使用析构函数,但这是另一个争论的问题。

在某些情况下,从init引发错误是不可避免的,但在init中做太多工作是一种糟糕的风格。你应该考虑制作一个工厂或一个伪工厂——一个返回已设置对象的简单类方法。

构造函数中使用最多的异常是:代码> ValueError < /C> >和<代码> TypeError < /代码>。您可能需要编辑这行代码,因为没有其他好方法可以指示构造函数中的错误条件,…这个答案非常有用。它不仅提到了“绿灯”,还提到了一个“析构函数”的例子。您的python代码在其
\uu del_u
中失败,因为它写得很糟糕。如果在C++中的析构函数中使用了<代码> > -> pHutoS> > Cuffe()/Cuff>,则完全相同的问题。在C++中,你不会那样做,你会让成员对象自己破坏。在Python中也一样。@埃里克,C++中不会有问题。事实上,它是C++中非常常见的一个习语。您建议成员对象销毁自己(在其析构函数中释放资源)——然后在编写成员类时也会出现同样的问题。
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()