考虑用python编写一个小型库,该库具有一个简单的方法x
,该方法接受参数ac
并返回计算值10/ac
。现在这里的收获是ac
不能是0
。所以我该如何处理这种情况。我想到了以下几种方法。
注意: :我已经研究了python异常处理,但是它只是说明如何使用try except
而不是我要问的特定问题。
方法1
def x(ac):
try:
return (10/ac)
except ZeroDivisionError:
raise ZeroDivisionError("ac cannot be zero")
以上代码仅使用普通try try块来捕获特定异常,并将异常引发给调用代码。因此调用代码将如下所示:
# some script...
try:
x(0)
except ZeroDivisionError as e:
log(e)
但是在这种情况下,我必须事先知道方法x
可能引发的所有可能的异常。
方法2:
def x(ac):
if ac == 0:
raise ValueError("ac cannot be zero") # or ZeroDivisionError??
else:
return (10/ac)
我猜想这与上一个语义上相同,除了使用if's
检查某些条件(我们知道可能会发生)并在此基础上引发异常。
预先知道该方法可能抛出什么异常也有同样的问题。
方法3
最后一个方法不处理库方法中的任何异常,而是将其留给客户端代码,但这显然没有任何意义,因为客户端将永远无法知道为什么在诉诸诸如此类之类的错误时到底会发生错误
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
如果不清楚,请告诉我。
答案 0 :(得分:5)
这取决于。像local.dvo[local.tf_validation_stg_l_indxd[count.index]]
或TypeError
这样的异常是标准的,通常表示编程错误。通常不需要明确这些内容。
其余的,您文档。作为API的作者,您有责任弄清楚其他开发人员可以从您的代码中期待什么行为。如果ValueError
是一个很好的记录信号,则将其添加到API的文档字符串中。那时,也无需显式捕获并再次引发它。不要指望阅读您的代码的用户,而是给他们好的文档。
对于许多API,定义您的 own 异常是有意义的。该实现可以捕获通用异常,也可以捕获其用于完成工作的第三方API的自定义异常,然后引发特定于API的异常,以向调用者发出错误消息,让他们处理问题。
有许多流行的Python库的例子,其中有例外。一些例子:
ZeroDivisionError
库commonly raised in response to other caught exceptions,其中许多来自支持requests
的其他API,例如urllib3
EOFError
is raised。这些项目的共同点是好的文档,该文档明确列出了使用该项目的任何人都应该知道的异常。