ane*_*kix 0 python exception-handling
考虑在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")
Run Code Online (Sandbox Code Playgroud)
上面的代码只是使用一个普通的try除了块来捕获特定的异常并引发调用代码的异常.所以调用代码看起来像这样:
# some script...
try:
x(0)
except ZeroDivisionError as e:
log(e)
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我必须事先知道方法x
可能引发的所有可能的异常.
方法2:
def x(ac):
if ac == 0:
raise ValueError("ac cannot be zero") # or ZeroDivisionError??
else:
return (10/ac)
Run Code Online (Sandbox Code Playgroud)
我猜这在语义上与前一个相同,只是为了检查一些条件(我们知道可能会发生)使用if's
和基于此提高异常.它也遇到了事先知道方法可能抛出的异常的相同问题.
方法3
最后一个方法是不处理库方法中的任何异常,而是将其留给客户端代码,但这显然没有意义,因为客户端永远无法知道为什么在诉诸类似的事情时可能会发生错误.
def x(ac):
return (10/ac)
try:
x(20)
except Exception as e:
log(e)
Run Code Online (Sandbox Code Playgroud)
现在这个方法只是一个操作的简单方法,但如果方法本身正在做一些复杂的事情,如连接到数据库然后获取一些结果.就像是 :
def x(db):
conn = db.connect('localhost')
results = connec.fetch(user_id=2)
return results
Run Code Online (Sandbox Code Playgroud)
如果有什么不清楚请告诉我.
这取决于.例外TypeError
或ValueError
标准的异常通常表示编程错误.通常没有必要明确这些.
其余的,你记录.作为API作者,您有责任明确其他开发人员可以从您的代码中获得的行为.如果ZeroDivisionError
是一个很好的文档信号,那么将其添加到API的docstring.此时,无需再次明确地捕获并再次提升它.不要指望用户阅读您的代码,而是给他们提供良好的文档.
对于许多API,定义自己的异常是有意义的.该实现可以捕获泛型异常,或者它用于执行工作的第三方API的自定义异常,然后引发特定于API的异常,以向调用者发出错误信号,让他们处理问题.
除了这些例外,还有流行的Python库的大量示例.一些例子:
requests
库定义了通常为响应其他捕获的异常而引发的自定义异常,其中许多异常来自其他API基础requests
,例如urllib3
EOFError
提出标准.这些项目的共同点是良好的文档,它明确指出使用该项目的任何人应该知道的异常.