广告

Python之异常和工具

2018-4-6 18:56 54 0 分类: 软件与OS 文集: Linux笔记
执行open操作?try一下吧!
做缓冲区读取?try一下吧!
操作容器?try一下吧!……
try、try、try,越try越开心,不try不快乐,世界因try而美好。
这里的try就是捕获异常并处理。虽然之前经常使用,但没有系统的学习它。因此俺今天会把这里好好梳理一遍,弄清楚什么是异常,以及异常的处理流程。

先看看异常的完整语法:
try/except: 捕获由Python或你引起的异常并恢复。
try/finally: 无论异常是否发生,执行清理行为。
raise: 手动在代码里触发异常。
assert: 有条件地在代码中触发异常。
with/as: 实现环境管理器。

异常的作用:
异常可以使我们从超级大的代码块中跳出来,跳到异常处理器。可以把异常看作一种结构化的超级goto。异常可以用作错误处理,如果我们读取了一个不存在的变量,没有异常的话,程序会出错并退出,有了异常,我们就可以继续执行以后的代码。异常可以用作事件通知,我们不用判断某段代码的状态值,而只要观察异常即可。异常可以做特殊情况处理,再怎么小心,代码也不可能判断并处理所有的意外,所以扔给异常就行了,没有想到的特殊情况,异常也会处理好。异常能够做终止行为无论实际发生了什么,finally都会保证最后的清理工作正常运行。异常能够做非常规控制流程,Python没有goto语句,我们可以使用异常来实现goto的部分功能。

怎么样?异常是不是非常强大?

示例代码:
x = ['abc',  'def',  'ghi']
print(x[4])
运行结果:
Exception "unhandled IndexError"
list index out of range

这里Python解释器为我们处理了异常。如果我们想自己捕获并处理这个异常:
x = ['abc',  'def',  'ghi']
try:
    print(x[4])
except:
    print('I will continue.')
运行结果:
I will continue.
这样,当我们在一个循环里持续获取x的第四个值时,如果有则打印第四个值,如果没有则继续执行之后的代码,而不是让程序出错并退出。

我们也可以手动引发异常,比如:
x = ['abc',  'def',  'ghi']
try:
    if x[0] == 'abc':
        raise IndexError
except IndexError:
    print('I will continue.')

assert也可以用来引发异常:
x = ['abc',  'def',  'ghi']
try:
    assert x[1] != 'def',  "Index 1 wrong!"
    print('Hello')
except:
    print('I will continue.')
运行结果:
I will continue.
Debug结果:
Exception "AssertionError"
Index 1 wrong!
I will continue.

assert一般用作调试,当它的条件为False的时候,就会触发异常。

定义我们自己的异常:
class NoCoffee(Exception):
    pass
try:
    raise NoCoffee()
except NoCoffee:
    print('No coffee! I cannot work!')
运行结果:
No coffee! I cannot work!

再看看finally的用法:
class NoCoffee(Exception):
    pass
try:
    raise NoCoffee()
except NoCoffee:
    print('No coffee! I cannot work!')
finally:
    print('Not gonna work anyway!')

运行结果:
No coffee! I cannot work!
Not gonna work anyway!

作为一名码农,可以这么任性么?
必须不行啊!老板,俺今天晚上加班,今天晚上加班,今天晚上必须加班!啊哈哈哈!

最后看看with/as:
with open('hello') as file:
    file.write('Hello World')
print('The End')
运行结果:
Exception "unhandled FileNotFoundError"
[Errno 2] No such file or directory: 'hello'

with/as只有在处理某些对象类型时才适用,而且它并不能让用户处理异常后的情形,因此还是try/except/finally更加通用。

结语:
由于Python有异常,所以我们可以不再编写检查错误的代码,无需判断状态位,无需担心罕见的特殊错误,无需那么谨小慎微和神经质。我们假设一切都工作正常,然后集中在业务功能的代码编写。

总之,异常是非常简单的工具,愉快的用起来吧!

----------------------------------------------------------------------------------------
以下是有关异常的、可能不需要了解、但最好了解一下、不了解也不影响、反正了解了有好处的细节。
来看一段完整的代码:
import os
import errno

x = ['abc',  'hello',  '123']
for i in range(4):
    try:
        print(x[i])
        open(x[i])
    except IndexError:
        print('Index wrong')
    except OSError as oe:
        print('error:',  os.strerror(oe.errno))
    except:
        print('Something wrong')
    else:
        print('I am good.')
    finally:
        print('Bye-bye!')
运行结果:
abc
error: No such file or directory
Bye-bye!
hello
error: No such file or directory
Bye-bye!
123
error: No such file or directory
Bye-bye!
Index wrong
Bye-bye!

try里面是我们的业务代码,except可以指定异常名称,如果异常不是指定名称的那种,则会使用没有指定异常的except。如果没有异常发生,则执行else的内容。不论有没有异常发生,都会执行finally中的内容。

广告

文章评论 0条评论)

登录后参与讨论
相关推荐阅读
DiracFatCat 2018-04-06 17:35
【博客大赛】Python之过度包装
上大学的时候,C语言实习课考试,答案是很简单的不超过5行的C语言代码。你一定不会相信,那个时候我写了大约30行,并且其中的25行是注释。因为某个时候看了一个文档,说C语言的函数注释必须要有,而且必须要...
DiracFatCat 2018-04-06 13:51
Python之装饰器
在使用Python搭建的轻量级Web框架Flask中,装饰器被大量使用。对于一种语言的高级特性,不需要在刚开始学习它的时候就全部掌握,而是可以在之后的应用中学习并理解。既然Flask用到了装饰器,现在...
DiracFatCat 2018-04-04 18:53
【博客大赛】Linux下使用Shadowsocks翻墙之简易攻略
本文并不是非常全面的教程,而是记录了我目前使用的可行的方法。在ssh翻墙已经被封得差不多了的时候,shadowsocks进入了俺的视野,尝试了一下,发现它上网的速度还不错。所以推荐给大家。第一步,购买...
DiracFatCat 2018-04-01 17:54
【博客大赛】Linux用户养成记——我的2013到2018
在EDN新版刚发布的时候,俺信誓旦旦的要正儿八经的写博文,还购买了Wiznote的云笔记服务。然后后续的事实证明这是一个flag,俺完全输给了自己的惰性,这几个月,工作以琐事居多,下班以堕落居多,技术...
DiracFatCat 2017-10-04 21:09
老舍《骆驼祥子》读书笔记
中学的时候,语文课本里有《骆驼祥子》节选。祥子拉车的生活艰苦,虎妞因愚昧害死了自己。除此之外,再没有其他的感想。鲁迅、张爱玲、徐志摩……话题人物很多,老舍不在其中。因老舍极其不浪漫,不浪漫的人勾不起少...
我要评论
0
0
广告
关闭 热点推荐上一条 /1 下一条