小编给大家分享一下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异常处理的小技巧