gpt4 book ai didi

python - 一种方法允许引发多种类型的异常还是只引发一种更好?

转载 作者:太空狗 更新时间:2023-10-30 02:30:27 25 4
gpt4 key购买 nike

我的问题是当一个方法可以引发两种(或更多)类型的异常但从调用者的角度来看它们的解释相同时,最好的(最“Pythonic”的)异常处理方法。

假设我有一个命名(名称是字符串)对象的集合。我希望此集合能够按索引或按名称返回项目。

class CollectionOfNamedItems:
def __init__(self, items):
self._dict = {item.name: item for item in items}
self._items = tuple(items)

def __getitem__(self, item):
if isinstance(item, str):
return = self._dict[item] # may raise KeyError
return self._items[item] # may raise IndexError

# usage: collection['X'] or collection[1]

我的问题是:根据我们是按索引还是按名称访问项目,__getitem__ 方法会引发 IndexErrorKeyError。这是引发异常的好方法吗?此方法的调用者必须捕获这两种类型的异常。还是在 __getitem__ 中捕获 KeyErrorIndexError 并引发 ValueError 会更好(可以这么说) (或其他一些?)以便调用者可以只捕获一种类型的异常,而不管传递的参数类型如何。

    def __getitem__(self, item):
try:
if isinstance(item, str):
return = self._dict[item] # may raise KeyError
return self._items[item] # may raise IndexError
except (KeyError, IndexError):
raise ValueError('invalid item')

另一方面,当我调用 collection[1.5]collection[None] 时,抛出 TypeError 似乎是合乎逻辑的。这是因为我觉得解释与上面的错误不同。

如有任何关于此主题的评论或想法,我将不胜感激。

最佳答案

一般来说,您应该总是尽可能地抛出最具体的异常。更重要的是,不要抛出旨在表示其他含义的异常类型。在您的情况下,ValueError 显然是错误的异常类型。

depending on whether we access the item by index or by name, the __getitem__ methods raises IndexError or KeyError. Is this a good way of raising exceptions?

是的,绝对是。如果您想同时支持索引和键访问,您应该同时实现“序列”和“映射”接口(interface),并根据您的方法的调用方式引发相应的异常。

这样做的原因是抽象:您将对象设计为可以按索引访问其内容的序列/列表类型,也可以作为映射/可以通过键访问其内容的字典类型。您类(class)的用户将选择这些接口(interface)中的一个,而不关心另一个。因此,他们期望不同类型的异常,并且不需要知道您的类的实现细节。

例如,如果您采用可以传递列表或其他行为类似于您的 CollectionOfNamedItems 的对象的通用函数,则该函数将使用包含 契约(Contract) __getitem__ 将为无效索引引发IndexError。如果您改为引发不同类型的异常,您将违反该契约(Contract),限制您的类的使用

“映射接口(interface)”也是如此。

The caller of this method would have to catch these two types of exceptions.

实际上,由于 KeyErrorIndexError 都是 LookupError 的子类,您方法的调用者不会区分这些情况 可以而且应该简单地捕获 LookupError:

try:
item = collection[id]
except LookupError:
# Could be KeyError or IndexError, we don't care.

关于python - 一种方法允许引发多种类型的异常还是只引发一种更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26827314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com