Effective Python(13): 合理利用try/ex

2019-10-11  本文已影响0人  warmsirius

一、Python的异常处理机制

Python的异常处理要考虑四种不同的时机,可用tryexceptelsefinally块来表述。

1. finally块

如果:

那就可以使用try/finally结构。

这种结构有一项常见的用途,就是确保程序能够可靠地关闭文件句柄(还有另外一种写法,参见第43条)

handle = open("/tmp/random_data.txt")  # May raise IOError
try:
    data = handle.read()  # May raise UnicodeDecodeError
finally:
    handle.close()

上面的代码中:

2. else块

如果try块没有发生异常,那么就执行else块。

有了这种else块,就可以尽量缩减try块内的代码量,使其更加易读。

举例

例如,要从字符串中加载JSON字典数据,然后返回字典里某个键所对应的值

import json


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

这种else子句,会把try/except后面的内容和except块本身区分开,使异常的传播行为变得更加清晰。

3. 混合使用

如果要在符合语句中把上面几种机制都用到,那就编写完整的try/except/else/finally结构。

举例

例如,要从文件中读取某项事物的描述信息,处理该事物,然后就地更新该文件。

UNDEFINED = object()


def divide_json(path):
    handle = open(path, "r+")  # May raise IOError
    try:
        data = handle.read()  # May raise UnicodeDecodeError
        op = json.loads(data)  # May raise ValueError
        value = (op["numerator"] / op["denominator"]) # May raise ZeroDivisionError
    except ZeroDivisionError as e:
        return UNDEFINED
    else:
        op["result"] = value
        result = json.dumps(op)
        handle.seek(0)
        handle.write(result)  # May raise IOError
        return value
    finally:
        handle.close()  # Always Run

二、总结

上一篇 下一篇

猜你喜欢

热点阅读