

作者 | luanhz
来源 | 小数志(ID:Datazhi)
头图 | 优快云 下载自东方IC
程序员每天遇到 bug 就像喝水吃饭一样稀松平常,关键在于怎么高效而不失优雅的面对这些 bug!所以,你还在固执的使用 try……except 吗?
为了提高程序运行的稳健性,几乎所有语言都提供了 try……except……用法, Python 也不例外。虽然 try……except……语法能够确保程序能够跳过异常代码片段,无论如何都继续执行下去,但有时主动的触发报错和异常也是一种行之有效的程序员装X护体方法。
本文主要介绍 Python 中的两个异常相关的关键字:assert 和 raise,前者用于断言发现潜在异常,后者用于触发报错,实际上二者功能有很大相近之处。

Python异常分类
Python内置了数十种Exception/Error类型,例如常见的如下几种:
IndexError,索引错误,例如引用了超出列表长度的索引
KeyError,键值错误,例如引用了字典中不存在的键值
NameError,未声明错误,例如引用了未赋值的对象或变量
SyntaxError,语法错误,广泛存在
IndentationError,缩进错误,这是Python摒弃花括号而用缩进区分代码段的特色产物
TypeError,类型错误,例如执行数字和字符串相加会引发此类错误
这些错误很常见,也比较直观易懂。但有没有考虑过主动触发这些错误呢?

assert:断言
assert 一般用于函数和类的内部,在执行具体逻辑前首先对输入参数和程序执行状态进行一定的检查和预判,仅当执行状态满足时才继续执行后续的逻辑,否则断言条件不满足,引发后续的提示。
assert 关键字基本用法为:
assert "条件判断", "条件不满足时输出的提示信息"
例如,设计一个两数相除的函数,那么应当在执行相除前检查:
两个输入参数是否为数值型
除数是否不为0
这一条件判断可用assert完成,并在条件不满足时优雅的提示报错:
def div(x, y):
assert isinstance(x, (float, int)) and isinstance(y, (float, int)), \
"param `x` and `y` expected to be 'int' or 'float' type"
assert y != 0, "param `y` should not to be exactly `0`"
return x/y
div(1, "2")
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-206-579e0bede4d8> in <module>
----> 1 div(1, "2")
<ipython-input-205-258ec937e818> in div(x, y)
1 def div(x, y):
2 assert isinstance(x, (float, int)) and isinstance(y, (float, int)), \
----> 3 "param `x` and `y` expected to be 'int' or 'float' type"
4 assert y != 0, "param `y` should not to be exactly `0`"
5 return x/y
AssertionError: param `x` and `y` expected to be 'int' or 'float' type
由于输入参数y是字符串类型,断言失败,引发断言错误
相较于 try……except……用法,assert 的最大意义在于能够及时发现程序中未按预期状态执行的错误,这在多人协作 coding 过程中,比 except 更能提供丰富的报错信息。

raise:触发异常
实际上,raise 关键字的哲学与 assert 是有相通之处的,只不过 assert 包含逻辑判断和触发提示信息两部分内容,而 raise 则只用于手动触发异常,且一般触发的是 Python 内置异常类型。某种程度上,raise 的灵活性要比 assert 低,在个人实际使用过程中也几乎很少用到。
raise关键字基本语法为:
raise 异常类名称(描述信息)
例如,仍以实现上述 div 函数功能为例,以 raise 关键字执行同样的断言功能,则可如下实现:
def div(x, y):
if not isinstance(x, (float, int)) or not isinstance(y, (float, int)):
raise TypeError("param `x` and `y` expected to be 'int' or 'float' type")
if y == 0:
raise ZeroDivisionError("param `y` should not to be exactly `0`")
return x/y
div(1, 0)
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-213-4267cdef819f> in <module>
----> 1 div(1, 0)
<ipython-input-212-dce337c4d91a> in div(x, y)
3 raise TypeError("param `x` and `y` expected to be 'int' or 'float' type")
4 if y == 0:
----> 5 raise ZeroDivisionError("param `y` should not to be exactly `0`")
6 return x/y
ZeroDivisionError: param `y` should not to be exactly `0`
由于除数为0,raise关键字触发异常
以上就是 Python 中这两个关键字的简单用法,单论其实质功能而言都称不上是不可或缺,甚至可能会觉得有些鸡肋,但不得不说在某些场景下二者其实都还是有用武之地,或许届时你的代码也可以如大佬一般:优雅高效,同时略显装X!
福 利优快云旗下公众号全新搜索技能上线啦!只要在公众号内回复消息就能自动回复想搜索的内容啦!现在体验有惊喜,每日参与搜索打卡,连续打卡满3天、7天、14天均有优快云精美礼品相送 百分百有礼!快戳每日体验优快云公众号搜索功能打卡
更多精彩推荐
☞倪光南、求伯君“出山”:爱解 Bug、无惧“35岁魔咒”、编码之路痛并快乐!
☞饿了么技术往事
☞我坦白!我是第五位飞上太空的程序员游客
☞赠书 | 图像分类问题建模方案探索实践
☞大神们都是如何在时间序列中进行特征提取的?看完就懂了!
☞Value DeFi遭黑客攻击始末,闪电贷这次又带走了700万美元
点分享点点赞点在看
本文聚焦Python,为提高程序稳健性,介绍了assert和raise两个异常相关关键字。assert用于断言发现潜在异常,能在多人协作中提供丰富报错信息;raise用于手动触发异常,灵活性稍低。还列举了Python常见异常类型,展示了两关键字的基本用法。
1088

被折叠的 条评论
为什么被折叠?



