在 python 中编写库时如何处理异常

how to handle exceptions while writing a library in python

考虑在 python 中编写一个小型库,它有一个简单的方法 x,它接受参数 ac & returns 计算值 10/ac .现在这里的问题是 ac 不能是 0。那么我如何在 method.there 中处理这种情况是我想到的这些方法。

注意: 我已经研究了 python 异常处理,但它只是展示了如何使用 try except不是我要问的具体问题。

方法一

def x(ac):
    try:
        return (10/ac)
    except  ZeroDivisionError:
        raise ZeroDivisionError("ac cannot be zero")

上面的代码只是使用一个普通的 try except 块来捕获特定的异常并将异常抛给调用代码。所以调用代码看起来像这样:

# some script...
try:
    x(0)
except ZeroDivisionError as e:
    log(e)

但在这种情况下,我必须事先知道该方法 x 可能引发的所有可能异常。

方法二:

def x(ac):
    if ac == 0:
        raise ValueError("ac cannot be zero") # or ZeroDivisionError??
    else:
        return (10/ac)

我想这在语义上与前一个相同,只是使用 if's 检查某些条件(我们知道可能会发生)并基于此引发异常。 它也遇到同样的问题,即事先知道该方法可能抛出什么异常。

方法三

最后一个方法不处理库方法中的任何异常,而是将其留给客户端代码,但这显然没有意义,因为客户端永远无法知道为什么在求助于像

def x(ac):
    return (10/ac)


    try:
       x(20)
    except Exception as e:
       log(e)

现在这个方法是一个只有一个操作的简单方法,但是如果方法本身正在做一些复杂的事情,比如连接到数据库然后获取一些结果怎么办。像 :

def x(db):
    conn = db.connect('localhost')
    results = connec.fetch(user_id=2)
    return results

如果有什么不清楚的地方请告诉我。

这取决于TypeErrorValueError 等异常是标准异常,通常表示编程错误。这些通常不需要明确说明。

剩下的,你文档。作为 API 作者,您有责任明确说明其他开发人员可以从您的代码中获得什么行为。如果 ZeroDivisionError 是文档的良好信号,则将其添加到 API 的文档字符串中。在这一点上,也没有必要再次明确地捕捉和引发它。不要指望用户阅读你的代码,而是给他们好的文档。

对于许多 API 来说,定义您自己的 异常是有意义的。该实现可以捕获通用异常,或者它用来完成工作的第 3 方 API 的自定义异常,然后引发一个 API 特定的异常以向调用者发出信号,表明有问题,让他们处理问题。

有大量流行的 Python 库示例,但有此类例外。一些例子:

这些项目的共同点是良好的文档,它明确指出了任何使用该项目的人都应该知道的例外情况。