解读The Python Tutorial(七)

异常

常见的异常如下,ZeroDivisionError是built-in的关键字,是异常类exception的子类。

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

异常的处理:

>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")
...

try的处理顺序
1,先走try里面的东西,如果没有异常,except 语句就不会执行。
2,try如果发生异常,则剩下的try代码不会被执行,转而执行相应的except name。
3,如果没有对应的except name则异常传递到上一级try语句。
4,如果始终没有try捕获到这个异常,则程序终止并抛出异常。

一个try可以配合多个except。

... except (RuntimeError, TypeError, NameError):
...     pass

except name捕获异常的规则:

class B(Exception): #祖类
    pass

class C(B):         #父类
    pass

class D(C):         #子类
    pass

for cls in [B, C, D]:   #打印B C D,和COBOL EVALUATE一样,配合最前面的WHEN。
    try:                   
        raise cls()
    except D:           #子类不能捕获父类。
        print("D")
    except C:
        print("C")
    except B:
        print("B")

如果改成以下 则打印B B B,即except父类可以捕获子类异常。

for cls in [B, C, D]:
    try:
        raise cls()
    except B:
        print("B")
    except C:
        print("C")
    except D:
        print("D")

没有name 的except相当于COBOL的other,接受所有异常。但通常我们只打印一些信息后然后raise再次抛出此异常让别处捕获。

except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

raise 可以抛出某个具体的异常,如:raise NameError(‘HiThere’)

else子句
else是可选 ,必须写在所有except的后面,当try没有任何异常时才执行else。应当把可能异常的代码写在try中,其余代码放在else里。

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

finally子句
用于清理工作(包括清理网络,数据库连接)。
finally是整个try最后执行的,而且一定会执行,不管理是否有异常。执行完finally后如果try中有异常没被捕获到,则会自动抛出该异常。

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0            #无异常,走else 
executing finally clause #无论有无异常,最后才执行finally
>>> divide(2, 0)
division by zero!
executing finally clause #有异常且被捕获到,同样是最后执行finally
>>> divide("2", "1")
executing finally clause #有异常且没被捕获,不走else,最后执行finally后,再次自动抛出此异常。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

with关键字

有些对象内置有预定义的清理工作,即封装好的try+finally

for line in open("myfile.txt"): #这代码执行完后,文件一直处在打开状态
    print(line, end="")
with open("myfile.txt") as f:   #with关键字使得这段代码执行后文件是自动关闭的
    for line in f:
        print(line, end="")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值