断言与异常

168 阅读2分钟

今天想写写异常和断言,也就是try/exceptassert的区别,以及它们各自的使用场景。当然,只是提供一点建议,具体如何使用还看个人喜好。

举个例子,假如我需要从数据库中读出一列人名(拼音),我的程序只能处理如下格式:zhang sanwang mazisitu jing,也就是姓 名(也可能是 名 姓),总之就是空格分隔的两个字符串。假设处理单个拼音的函数是deal_name(name)

如果有要求,人名拼音必须是这种格式,要保持数据的规范性。 这时候,assert就比较合适。

def deal_name(name):
    assert len(name.split()) == 2
    ...

这样,如果assert的条件len(name.split()) == 2不满足,程序就会直接抛出assertionError异常并终止运行。

下面写法与上面实现功能相同。

def deal_name(name):
    if len(name.split()) != 2:
        raise AssertionError()
    ...

可如果要求没有那么严格,出现不规范数据时,程序不要崩,只打印错误日志就行。那要做的就只是参数验证。

def deal_name(name):
    if len(name.split()) != 2:
        logging.error('Name format is wrong!')
        return
    ...

assert用在这里,只是为了方便。为了让程序在出现非法输入时快速崩掉,任何一种异常都可做到这点(如果只是做参数验证,最好不要用assert,而是定义自己的异常类)。

assert最常见的用法是 程序员写代码时的debug工具。 如果函数中使用了assert condition ,那么意思是这条语句下面的代码,只会遇到 condition 这一种情况(按照代码的逻辑),如果出现其它情况,那肯定是代码出了问题,此时就需要找 bug,修 bug了。

上面函数写成异常处理的样子如下:

def deal_name(name):
    try:
        # do something
        ...
    except Exception as e:
        logging.error(e)
        return 
    else:
        # do something else
        ...

总结: 对于一个函数,如果我(程序员)觉得它不会发生异常,就使用断言。如果我知道它可能会发生异常(由于不合理的输入或者包含文件操作),就应该使用异常处理,并定义自己的异常类。另外,不要滥用异常处理。每个try中最好只包含一条可能引发异常的语句。