Python异常处理的小技巧

  介绍

小编给大家分享一下Python异常处理的小技巧,希望大家阅读完这篇文章后大所收获、下面让我们一起去探讨吧!

如果你用Python编程,那么你就无法避开异常,因为异常在这门语言里无处不在。打个比方,当你在脚本执行时按ctrl + c退出,解释器就会产生一个KeyboardInterrupt异常。而KeyError, ValueError, TypeError等更是日常编程里随处可见的老朋友。

异常处理工作由“捕获”和“抛”出两部分组成。“捕获”指的是使用试一试……除了包裹特定语句,妥当的完成错误流程处理,而恰当的使用提高主动“抛”出异常,更是优雅代码里必不可少的组成部分。

在这篇文章里,我会分享与异常处理相关的3个好习惯。继续阅读前,我希望你已经了解了下面这些知识点:

异常的基本语法与用法(建议阅读官方文档错误和异常)

为什么要使用异常代替错误返回(建议阅读《让函数返回结果的技巧》)

为什么在写Python时鼓励使用异常(建议阅读“Python编写清洁:使用例外”)

三个好习惯

<强> 1。只做最精确的异常捕获

假如你不够了解异常机制,就难免会对它有一种天然恐惧感。你可能会觉得:异常是一种不好的东西,好的程序就应该捕获所有的异常,让一切都平平稳稳的运行。而抱着这种想法写出的代码,里面通常会出现大段含糊的异常捕获逻辑。

让我们用一段可执行脚本作为样例:

#,- *安康;编码:utf-8  - * -   import 请求   import 再保险   def  save_website_title (url,文件名):   ,,,“““获取某个地址的网页标题,然后将其写入到文件中   ,,,:返回:,如果成功保存,返回,真的,否则打印错误,返回,假的   ,,,,,,   ,,,试一试:   ,,,,,,,resp =, requests.get (url)   ,,,,,,,obj =, re.search (" # 39; & lt; title> (. *) & lt;/title> & # 39;,, resp.text)   ,,,,,,,if  not  obj:   ,,,,,,,,,,,印刷(& # 39;节省;失败:,title  tag  not  found 拷贝page 内容# 39;)   ,,,,,,,,,,,return 错误的   ,,,,,,,title =, obj.grop (1)   ,,,,,,,with 开放(文件名,& # 39;w # 39;), as 外交政策:   ,,,,,,,,,,,fp.write(标题)   ,,,,,,,,,,,return 真实的   ,,,except 例外:   ,,,,,,,印刷(f # 39;节省;失败:,unable 用节省;title  of  {url},用{文件名}& # 39;)   ,,,,,,,return 错误的   def  main ():   ,,,save_website_title (& # 39; https://www.qq.com& # 39;,, & # 39; qq_title.txt& # 39;)   if  __name__ ==, & # 39; __main__ # 39;:   ,,,main ()

脚本里的save_website_title函数做了好几件事情。它首先通过网络获取网页内容,然后利用正则匹配出标题,最后将标题写在本地文件里。而这里有两个步骤很容易出错:网络请求与本地文件操作,所以在代码里,我们用一个大大的尝试……除了语句块,将这几个步骤都包裹了起来。安全第一。

那么,这段看上去简洁易懂的代码,里面藏着什么问题呢?

如果你旁边刚好有一台安装了Python的电脑,那么你可以试着跑一遍上面的脚本。你会发现,上面的代码是不能成功执行的。而且你还会发现,无论你如何修改网址和目标文件的值,程序仍然会报错“保存失败:无法…”。为什么呢?

问题就藏在这个硕大无比的尝试……除了语句块里。假如你把眼睛贴近屏幕,非常仔细的检查这段代码。你会发现在编写函数时,我犯了一个小错误,我把获取正则匹配串的方法错打成了obj.grop(1),少了一个& # 39;u # 39; (obj.group (1))。

但正是因为那个过于庞大,含糊的异常捕获,这个由打错方法名导致的原本该被抛出的AttibuteError却被吞噬了。从而给我们的调试过程增加了不必要的麻烦。

异常捕获的目的,不是去捕获尽可能多的异常假。如我们从一开始就坚持:只做最精准的异常捕获。那么这样的问题就根本不会发生,精准捕获包括:

永远只捕获那些可能会抛出异常的语句块

尽量只捕获精确的异常类型,而不是模糊的异常

依照这个原则,我们的样例应该被改成这样:

得到requests.exceptions  import  RequestException   def  save_website_title (url,文件名):   试一试:   时间=resp  requests.get (url)   except  RequestException  as  e:   print (f # 39;节省;失败:,unable 用get  page 内容:,{e} & # 39;)   return 假   #,这段正则操作本身就是不应该抛出异常的,所以我们没必要使用,try 语句块   #,假如,group 被误打成了,grop 也没关系,程序马上就会通过,AttributeError 来   #,告诉我们。   时间=obj  re.search (" # 39; & lt; title> (. *) & lt;/title> & # 39;,, resp.text)   if  not  obj:   打印(& # 39;节省;失败:,title  tag  not  found 拷贝page 内容# 39;)   return 假   时间=title  obj.group (1)   试一试:   with  open (filename, & # 39; w # 39;), as 外交政策:   fp.write(标题)   except  IOError  as  e:   print (f # 39;节省;失败:,unable 用write 用file {文件名}:,{e} & # 39;)   return 假   其他:   return 真正的

Python异常处理的小技巧