每日10行代码96:编写高质量python代码方法13——合理利用try/except/else/finally结构中的每个代码块

python程序的异常处理可能要考虑四种不同的时机。这些时机可以用try , except, else和finally块来表述。复合语句中的每个块都有特定的用途,它们可以构成多中有用的组合方式。

  1. finally块
    如果既要将异常向上传播,又要在异常发生时执行清理工作,那就可以用try/finally结构。这种结构有一项常见的爱得得体,就是确保程序能够可靠地关闭文件句柄。
handle = open('tmp/random_data.txt')    # May raise IOError
try:
    data = handle.read()     # May raise UnicodeDecodeError
finally:
    handle.close()   #always runs after  try:    

在上面这段代码中,read方法抛出的异常会向上传播给调用方,而finally块中的handle.close方法则一定能够执行。open方法必须放在try块外面,因为如果打开文件时发生异常,那么程序应该跳过finally块。(这个例子应该确保第一行的open不出错,如果不确定,个人觉得可以再套一层try语句)
2. else块
try/except/else结构可以清晰地描述哪些异常会由自己的代码来处理、哪些异常会传播到上一级。如果try块没有发生异常,那么就执行else块。有了这种else块,我们可以尽量缩减try块内的代码量,使其更加易读。例如,要从字符串中加载json字典数据,然后返回字典里某个键所对应的值。

def load_json_key(data,key):
    try:
        result_dict = json.loads(data)
    except ValueError as e:
        raise KeyError from e
    else:
        return result_dict[key]

如果数据不是有效的json格式,那么用json.loads解码时,会产生ValueError. 这个异常会由except块来捕获并处理。如果能够解码,那么else块里的查找语句就会执行,它会根据键来查出相关的值。查询若有异常,则该异常会向上传播,因为查询语句并不在刚才那个try块的范围内。这种else子句,会把try/except后面的内容和except块本身区分开,使异常的传播行为变得更加清晰。
3. 混合使用
如果要在复合语句中把上面几种机制都用到,那就编写完整的try/except/else/finally结构。例如,要从文件读取某项事务的描述信息,处理该事务,然后就地更新该文件。为了实现此功能,我们可以用try块来读取文件并处理内容,用except块来应对try块中可能发生的相关异常,用else块来实时地更新文件并把更新中可能了同岁的异常回报给上级代码,然后用finally块来清理文件句柄。

UNDEFINED = object()

def divide_json(path):
    handle = open(path, 'r+')
    try:
        data = handle.read()
        op = json.loads(data)
        value = (
            op['numerator']
            op['denominator'])
    except ZeroDivisionError as e:
        return UNDEFINED
    else:
        op['result'] = Value
        result = json.dumps(op)
        handle.seek(0)
        handle.write(result)
        return Value 
    finally:
        handle.close()

这种写法很有用,因为这四块代码配合得非常到们。例如,即使else块在写入result数据时发生异常,finally块中关闭文件句柄的那行代码,也依然能执行。

要点:

  1. 无论try块是否发生异常,都可利用try/finally复合名句种的finally块来执行清理工作。
  2. else块可以用来缩减try块中的代码量,并把没有发生异常时所要执行的语句try/except代码块隔开。
  3. 顺利运行try块后,若想使某些操作能在finally块的清理代码之前执行,则可将这些操作代码写到else块中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值