当前位置: 首页 > 科技观察

走出苦海,从避免滥用try...except...开始

时间:2023-03-21 00:36:04 科技观察

很多人在写Python代码的时候都喜欢用try...exceptException,更何况一层一层,是否有到底用还是不用,先说说:ss="dp-xml">ss="alt">deffunc():ss="">try:ss="alt">"函数内部代码"ss="">exceptExceptionase:ss="alt">print('函数错误:',e)ss="">ss="alt">ss="">try:ss="alt">func()ss="">exceptExceptionase:ss="alt">print('Functionerror:',e)不管有没有必要,总之就是放在try上有安全感...除了……套娃套太多之后,噩梦就开始了。我们来看看下面的报错:告诉我,是哪个函数出了问题?如果你饱受滥用try...except...的困扰,以下三个方法可以让你脱离苦海。在程序开发初期暴露问题,不要用try...except...。让Python暴露问题。通过Python的报错,可以直接看出是哪一行代码有问题,是什么问题。甚至有些时候,不仅不需要捕获异常,还应该主动抛出异常。项目完成后,如果你在做第三方库供别人调用,那么你应该多抛出异常,而不是擅自返回正常的错误信息。比如你要实现一个函数:query_name,输入参数是一个数字id,输出用户名。你可以这样写:ss="dp-xml">ss="alt">defquery_name(user_id):ss="">ifnotisinstance(user_id,int):ss="alt">return{'success':False,'msg':'Useridmustbeainteger'}ss="">...但其实更好的办法是直接抛出异常:ss="dp-xml">ss="alt">defquery_name(user_id):ss="">ifnotisinstance(user_id,int):ss="alt">raiseException('Useridmustbeaninteger'}ss="">...甚至在某些情况下,你可以使用Python的断言:ss="dp-xml">ss="alt">defquery_name(user_id):ss="">assertisinstance(user_id,int),'useridmustbeaninteger'ss="alt">...As如下图所示:只要user_id不是整数,就会抛出AssertionError。当我们直接执行python3xxx.py时,这些断言语句会正常工作。但是我们可以使用python3-oxxx.py让Allassertxxxstatementsareinvalid.尽早暴露异常,尽早解决问题。捕获特定异常而不是所有异常,只捕获你清楚知道的异常。你知道为什么这些异常发生了,你就知道该怎么解决了。例如,我们使用请求来请求网站。由于网络问题,有时请求可能会超时。一旦超时,requests就会抛出超时异常,如下图所示:这种情况下,你知道这个地方可能会发生TimeoutException,你知道发生了,就重试。所以,可以catch这个异常:大家注意了,在这个地方,requests执行了.json()方法。如果url返回的内容可能不是json格式的字符串,这里会报JSONDecodeError,如下图:如果不区分,直接用exceptException,怎么知道是可以正常处理的超时问题吗?,或者您是否从您通常无法处理的网站内容中返回异常?因此,只捕获您知道发生原因并且知道如何处理的异常。对于无法预测或无法处理的异常,直接抛出。不要自己拿。如果实在不得已才强行打印错误信息,必须使用try...exceptException。如何打印出具体的错误位置?其实方法是有的。那就是使用Python自带的traceback模块。它的用法很简单:ss="dp-xml">ss="alt">importtracebackss="">ss="alt">try:ss="">1+'a'ss="alt">exceptException:ss="">print(traceback.format_exc())运行效果如下图所示:成功打印出异常所在行数和具体错误类型。显然,这样写需要无缘无故写很多代码。综上所述,try...except...会让你的代码看起来没有问题,但也可能掩盖问题,让你无法发现问题出在哪里。所以,从阅读这篇文章开始,删除不必要的try...except....拥抱异常,让你无法处理的异常被抛出。如果程序出现问题,应该停止运行,而不是带着问题继续运行,这样可能会演变成更大的问题。