在 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
如果有什么不清楚的地方请告诉我。
这取决于。 TypeError
或 ValueError
等异常是标准异常,通常表示编程错误。这些通常不需要明确说明。
剩下的,你文档。作为 API 作者,您有责任明确说明其他开发人员可以从您的代码中获得什么行为。如果 ZeroDivisionError
是文档的良好信号,则将其添加到 API 的文档字符串中。在这一点上,也没有必要再次明确地捕捉和引发它。不要指望用户阅读你的代码,而是给他们好的文档。
对于许多 API 来说,定义您自己的 异常是有意义的。该实现可以捕获通用异常,或者它用来完成工作的第 3 方 API 的自定义异常,然后引发一个 API 特定的异常以向调用者发出信号,表明有问题,让他们处理问题。
有大量流行的 Python 库示例,但有此类例外。一些例子:
requests
图书馆 defines custom exceptions which are commonly raised in response to other caught exceptions, many of which come from other APIs underpinning requests
, such as urllib3
- Werkzeug 是一个可用于构建 WSGI 堆栈(Web 应用程序)的库,它定义了 HTTP exceptions, which upstream users such as Flask can catch and handle。
- Pandas 数据分析工具包 defines several custom exceptions and warnings, which are in used to indicate issues such as CSV input parsing, triggered by 3rd-party exceptions。
- Pillows,一个图片库 documents when a standard
EOFError
is raised 与此相关。
这些项目的共同点是良好的文档,它明确指出了任何使用该项目的人都应该知道的例外情况。
考虑在 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
如果有什么不清楚的地方请告诉我。
这取决于。 TypeError
或 ValueError
等异常是标准异常,通常表示编程错误。这些通常不需要明确说明。
剩下的,你文档。作为 API 作者,您有责任明确说明其他开发人员可以从您的代码中获得什么行为。如果 ZeroDivisionError
是文档的良好信号,则将其添加到 API 的文档字符串中。在这一点上,也没有必要再次明确地捕捉和引发它。不要指望用户阅读你的代码,而是给他们好的文档。
对于许多 API 来说,定义您自己的 异常是有意义的。该实现可以捕获通用异常,或者它用来完成工作的第 3 方 API 的自定义异常,然后引发一个 API 特定的异常以向调用者发出信号,表明有问题,让他们处理问题。
有大量流行的 Python 库示例,但有此类例外。一些例子:
requests
图书馆 defines custom exceptions which are commonly raised in response to other caught exceptions, many of which come from other APIs underpinningrequests
, such asurllib3
- Werkzeug 是一个可用于构建 WSGI 堆栈(Web 应用程序)的库,它定义了 HTTP exceptions, which upstream users such as Flask can catch and handle。
- Pandas 数据分析工具包 defines several custom exceptions and warnings, which are in used to indicate issues such as CSV input parsing, triggered by 3rd-party exceptions。
- Pillows,一个图片库 documents when a standard
EOFError
is raised 与此相关。
这些项目的共同点是良好的文档,它明确指出了任何使用该项目的人都应该知道的例外情况。