容器类是处理错误还是只是提出它们?

时间:2015-09-06 00:10:03

标签: python error-handling

我正在使用Python创建一个伪 - Vector类,我想知道我是否应该进行错误检查,如果是,那么程度如何。

例如,当有人执行以下操作时:

vec = Vector(1,2,3,4)
# vec is now [1,2,3,4]
vec[100] = 12

我的IndexError生成的__setitem__应该怎么办?我的__setitem__应该包含:

if index < 0 or index >= len(self.vector):
    raise IndexError("Index out of bounds")

或者应该是

try:
    if index < 0 or index >= len(self.vector):
        raise IndexError("Index out of bounds")
except IndexError as e:
    print(str(e))

通常情况下容器类的用户是否会处理错误,或容器本身是否知道处理错误?

2 个答案:

答案 0 :(得分:1)

如果您的容器会导致错误(通过处理错误),您将永远不会发现使用Vector错误的代码问题。

换句话说,如果指定超出范围的索引是正确的行为,那么只处理Vector类中的异常,以及容器的预期设计的一部分。

对于绝大多数用例,您的班级不应该处理IndexError;尝试分配超出范围的索引是一个无效的用例。

答案 1 :(得分:1)

我认为当您的自定义类包装其他类时(例如在list之上构建的自定义容器类),有两种情况需要考虑。

  1. 包装类和包装器对有效输入都有相同的期望,并且应该在无效输入上引发相同的例外。在这种情况下,您不需要处理异常,因为内部包装类将引发异常是合适的。您可能希望处理此类异常的唯一可能原因是隐藏类的内部工作方式(在这种情况下,您可能希望在异常处理程序中raise SomeException from None隐藏内部详细信息)。

    < / LI>
  2. 包装器的行为应该与包装类不同。在这种情况下,您可能需要提前检查和/或修改输入,或者捕获和抑制包装代码引发的异常。例如,列表允许负索引,如果您不希望容器这样做,则需要检查传入的索引是否为否定(如果是,则提出IndexError)。或者,如果您希望允许越界索引无限制地环绕(以便将任何索引i视为i % len(self.vector)),您可以使用try / {{1} }}语句用于捕获内部列表引发的except并使用修改后的索引重试(虽然想到它,您可能只是无条件地修改索引)。

  3. 所以,我认为没有一个正确的答案。详细信息取决于您的集合的行为应该如何工作以及它与您要包装的列表的不同之处。