在Python类中,当在运行该方法之前必须更改类的某些其他属性时,我应该从实例方法中引出什么类型的错误?
我来自C#背景,我会使用 InvalidOperationException
,"the exception that is thrown when a method call is invalid for the object's current state",但我找不到等效的built-in exception in Python .
当问题出在函数参数时,我一直在提高 ValueError
("raised when a built-in operation or function receives an argument that has the right type but an inappropriate value") . 我认为这在技术上是 self
参数的无效值;这是治疗它的正确方法吗?例如,这是惯用语: raise ValueError("self.foo must be set before running self.bar()")
?
6 回答
在这种情况下,
ValueError
是最好的事情 . 对于python,您应该更喜欢使用built-in exception types而不是创建自己的 . 你应该只创建新的异常类型,当你期望你需要捕获它并且行为方式与你出现的方式非常不同时 - 你're not expecting to catch this because it would indicate an error in using the class in question. For this it'不值得创建一个新类型只是为了让它有另一个名字 - 这就是消息字符串你传给ValueError()
是为了 .是否有可能重构您的课程,以便无法实现这种无效状态?
ValueError
对我来说没问题,但我认为AssertionError
更合适 . 基本上,它违反了API设计者的断言 .你的意思是什么?我没有理由为什么你不应该使用子类异常来创建自己的Exception类型,但这可能就是我出来的旧的Oracle PL / SQL Dev ......
我发现
RuntimeError
是所有内置异常中最合适的信号无效状态 .请参阅此示例,了解它在CPython中的使用方式:
值得注意的是,即使CPython实现本身与库之间特定异常类型的使用也不一致 . 有时使用
ValueError
,但在我看来,它从Python文档中的描述表明它的使用是为其他情况保留的 .RuntimeError
是一个更普遍的例外,当一段代码无法正常运行时,如果给出了正确的输入,则应该使用它,这有点类似于对象处于无效状态时的情况 .我认为pythonic方式不是让对象处于这样一种状态,即方法调用不会崩溃,尽管处于错误状态 . 这些是最难找到的错误,因为程序最终推翻的地方并不是错误发生的地方 .
例如 .
不应该做的事情是这样的
我认为这是在pythonic的座右铭:
如果异常状态是在正常执行过程中可能发生的事情,而不是通过滥用该类而导致用户错误,那么您应该创建自己的异常似乎是合理的 . StopIteration和迭代器就是一个例子 .
我认为当问题出在函数参数上时,你应该提出一个ValueError,当问题是必须设置的属性时AttributeError .
此外,您可以将
AttributeError
子类化为更具体的异常,但我认为没有必要 . 带有错误消息的AttributeError
异常足够清楚 .