原创 Python之异常和工具

2018-4-6 18:56 2039 16 16 分类: 软件与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)
        open(x)
    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条评论)

登录后参与讨论
我要评论
0
16
关闭 站长推荐上一条 /2 下一条