Python 异常处理核心:assert 断言机制与实战应用
本文深入解析 Python 中的 assert 断言机制,阐述其作为条件判断触发异常的简洁用法,并对比其与 raise 关键字的差异。通过具体代码示例展示断言语法,并结合面向对象案例演示如何在学生信息管理中添加异常捕获与批量处理功能,帮助开发者掌握高效的代码校验技巧。
断言机制概述
本节将介绍异常处理的最后一个重要知识点:断言(Assertion)。断言用于验证一个表达式,当该表达式的计算结果为 False 时,系统会自动触发异常。这里的表达式可以灵活对应到各种场景,例如条件语句中的判断逻辑,或是 while 循环中的退出条件声明。
无论是常规的条件判断还是循环控制,核心都在于对事物状态进行 True 或 False 的判定。断言机制与此类似,一旦检测到后续跟随的表达式结果为 False,它就会主动抛出异常,从而中断当前流程或提示错误。
在 Python 语言中,assert 是用于实现断言的关键字。初看之下,它似乎与 raise 关键字的功能相似,但两者的使用逻辑有显著区别。assert 的使用方式更为简洁优雅:它首先对表达式进行判断,仅当判断结果为假时才抛出异常;相比之下,raise 则是直接、生硬地抛出一个指定的异常,缺乏前置的条件判断过程。
以验证自定义函数返回结果为例,若使用 raise,开发者需要手动编写 if 条件语句来检查断言条件,随后再调用 raise 抛出异常;而使用 assert,仅需一行代码即可轻松完成同样的校验任务,大大简化了代码结构。
断言功能与语法
接下来详细解析断言的功能定义及其具体语法规范。
断言的核心功能在于:它是一个用于判断的表达式机制。当该表达式的条件返回值为 False 时,程序将触发异常。这是确保代码逻辑正确性的重要手段。
断言的基本语法格式如下所示:
# 用法:
assert exception, message
# 参数:
# exception:表达式,一般是判断相等;或者是判断是某种数据类型的 bool 判断的语句,再决定是否抛出异常
# message:指的是具体的错误信息,选填参数,可以不填写。(但是建议还是填写上)
# 返回值:无返回值(虽然表达式有返回值,但 assert 没有;表达式为 Treu , assert 将不会触发任何异常)通过一个简单示例来直观理解断言的运行效果:
assert 1 != 1, '返回结果 \'False\' 1 等于 1'
# >>> 执行结果如下:
# >>> AssertionError: 返回结果 'False' 1 等于 1
# ********************************************
assert 1 > 2, '返回结果 \'False\' ,抛出异常'
# >>> 执行结果如下:
# >>> AssertionError: 返回结果 'False' ,抛出异常
断言实战:面向对象异常处理
下面进行断言的实际应用演练。
我们将结合之前面向对象章节中“从面向函数转向面向对象”的 Python 学习案例,在此基础上增加异常处理机制及异常捕获逻辑,并进一步扩展实现批量添加数据的功能。
完整的参考源码如下:
"""
@Author:Neo
@Date:2020/1/16
@Filename:students_info.py
@Software:Pycharm
"""
class NotArgError(Exception):
def __init__(self, message):
self.message = message
class StudentInfo(object):
def __init__(self, students):
self.students = students
def get_by_id(self, student_id):
return self.students.get(student_id)
def get_all_students(self):
for id_, value in self.students.items():
print('学号:{}, 姓名:{}, 年龄:{}, 性别:{}, 班级:{}'.format(
id_, value['name'], value['age'], value['sex'], value['class_number']
))
return self.students
def add(self, **student):
try:
self.check_user_info(**student)
except Exception as e:
raise e
self.__add(**student)
def adds(self, new_students):
for student in new_students:
try:
self.check_user_info(**student)
except Exception as e:
print(e, student.get('name'))
continue
self.__add(**student)
def __add(self, **student):
new_id = max(self.students) + 1
self.students[new_id] = student
def delete(self, student_id):
if student_id not in self.students:
print('{} 并不存在'.format(student_id))
else:
user_info = self.students.pop(student_id)
print('学号是{}, {}同学的信息已经被删除了'.format(student_id, user_info['name']))
def deletes(self, ids):
for id_ in ids:
if id_ not in self.students:
print(f'{id_} 不存在学生库中')
continue
student_info = self.students.pop(id_)
print(f'学号{id_} 学生{student_info["name"]} 已被移除')
def update(self, student_id, **kwargs):
if student_id not in self.students:
print('并不存在这个学号:{}'.format(student_id))
try:
self.check_user_info(**kwargs)
except Exception as e:
raise e
self.students[student_id] = kwargs
print('同学信息更新完毕')
def updates(self, update_students):
for student in update_students:
try:
id_ = list(student.keys())[0]
except IndexError as e:
print(e)
continue
if id_ not in self.students:
print(f'学号{id_} 不存在')
continue
user_info = student[id_]
try:
self.check_user_info(**user_info)
except Exception as e:
print(e)
continue
self.students[id_] = user_info
print('所有用户信息更新完成')
def search_users(self, **kwargs):
assert len(kwargs) == 1, '参数数量传递错误'
values = list(self.students.values())
key = None
value = None
result = []
if 'name' in kwargs:
key = 'name'
value = kwargs[key]
elif 'sex' in kwargs:
key = 'sex'
value = kwargs['sex']
elif 'class_number' in kwargs:
key = 'class_number'
value = kwargs[key]
elif 'age' in kwargs:
key = 'age'
value = kwargs[key]
else:
raise NotArgError('没有发现搜索的关键字')
for user in values: # [{name, sex, age, class_number}, {}]
if value in user[key]:
result.append(user)
return result
def check_user_info(self, **kwargs):
assert len(kwargs) == 4, '参数必须是4个'
if 'name' not in kwargs:
raise NotArgError('没有发现学生姓名参数')
if 'age' not in kwargs:
raise NotArgError('缺少学生年龄参数')
if 'sex' not in kwargs:
raise NotArgError('缺少学生性别参数')
if 'class_number' not in kwargs:
raise NotArgError('缺少学生班级参数')
name_value = kwargs['name'] # type(name_value)
age_value = kwargs['age']
sex_value = kwargs['sex']
class_number_value = kwargs['class_number']
# isinstace(对比的数据, 目标类型) isinstance(1, str)
if not isinstance(name_value, str):
raise TypeError('name应该是字符串类型')
if not isinstance(age_value, int):
raise TypeError('age 应该是整型')
if not isinstance(sex_value, str):
raise TypeError('sex应该是字符串类型')
if not isinstance(class_number_value, str):
raise TypeError('class_number应该是字符串类型')
students = {
1: {
'name': 'Neo',
'age': 18,
'class_number': 'A',
'sex': 'boy'
},
2: {
'name': 'Jack',
'age': 16,
'class_number': 'B',
'sex': 'boy'
},
3: {
'name': 'Lily',
'age': 18,
'class_number': 'A',
'sex': 'girl'
},
4: {
'name': 'Adem',
'age': 18,
'class_number': 'C',
'sex': 'boy'
},
5: {
'name': 'HanMeiMei',
'age': 18,
'class_number': 'B',
'sex': 'girl'
}
}
if __name__ == '__main__':
student_info = StudentInfo(students)
user = student_info.get_by_id(1)
student_info.add(name='Marry', age=16, class_number='A', sex='girl')
users = [
{'name': 'Atom', 'age': 17, 'class_number': 'B', 'sex': 'boy'},
{'name': 'Lucy', 'age': 18, 'class_number': 'C', 'sex': 'girl'}
]
student_info.adds(users)
student_info.get_all_students()
print('------------------------------------------------------')
# >>> 执行结果如下:
# >>> 学号:1, 姓名:Neo, 年龄:18, 性别:boy, 班级:A
# >>> 学号:2, 姓名:Jack, 年龄:16, 性别:boy, 班级:B
# >>> 学号:3, 姓名:Lily, 年龄:18, 性别:girl, 班级:A
# >>> 学号:4, 姓名:Adem, 年龄:18, 性别:boy, 班级:C
# >>> 学号:5, 姓名:HanMeiMei, 年龄:18, 性别:girl, 班级:B
# >>> 学号:6, 姓名:Marry, 年龄:16, 性别:girl, 班级:A
# >>> 学号:7, 姓名:Atom, 年龄:17, 性别:boy, 班级:B
# >>> 学号:8, 姓名:Lucy, 年龄:18, 性别:girl, 班级:C
# >>> ------------------------------------------------------
student_info.deletes([7, 8])
student_info.get_all_students()
print('------------------------------------------------------')
# >>> 执行结果如下:
# >>> ------------------------------------------------------
# >>> 学号7 学生Atom 已被移除
# >>> 学号8 学生Lucy 已被移除
# >>> 学号:1, 姓名:Neo, 年龄:18, 性别:boy, 班级:A
# >>> 学号:2, 姓名:Jack, 年龄:16, 性别:boy, 班级:B
# >>> 学号:3, 姓名:Lily, 年龄:18, 性别:girl, 班级:A
# >>> 学号:4, 姓名:Adem, 年龄:18, 性别:boy, 班级:C
# >>> 学号:5, 姓名:HanMeiMei, 年龄:18, 性别:girl, 班级:B
# >>> 学号:6, 姓名:Marry, 年龄:16, 性别:girl, 班级:A
# >>> ------------------------------------------------------
student_info.updates([
{1: {'name': 'Jone', 'age': 18, 'class_number': 'A', 'sex': 'boy'}},
{2: {'name': 'Nike', 'age': 18, 'class_number': 'A', 'sex': 'boy'}}
])
student_info.get_all_students()
print('------------------------------------------------------')
# >>> 执行结果如下:
# >>> ------------------------------------------------------
# >>> 所有用户信息更新完成
# >>> 学号:1, 姓名:Jone, 年龄:18, 性别:boy, 班级:A
# >>> 学号:2, 姓名:Nike, 年龄:18, 性别:boy, 班级:A
# >>> 学号:3, 姓名:Lily, 年龄:18, 性别:girl, 班级:A
# >>> 学号:4, 姓名:Adem, 年龄:18, 性别:boy, 班级:C
# >>> 学号:5, 姓名:HanMeiMei, 年龄:18, 性别:girl, 班级:B
# >>> 学号:6, 姓名:Marry, 年龄:16, 性别:girl, 班级:A
# >>> ------------------------------------------------------
result = student_info.search_users(name='d')
print(result)
print('------------------------------------------------------')
# >>> 执行结果如下:
# >>> [{'name': 'Adem', 'age': 18, 'class_number': 'C', 'sex': 'boy'}]
result = student_info.search_users(name='小')
print(result)
print('------------------------------------------------------')
# >>> 执行结果如下:
# >>> ------------------------------------------------------
# >>> []
# >>> ------------------------------------------------------
result = student_info.search_users(name='')
print(result)
result = student_info.search_users(name='小')
print(result)
print('------------------------------------------------------')
# >>> 执行结果如下:
# >>> ------------------------------------------------------
# >>> [{'name': 'Jone', 'age': 18, 'class_number': 'A', 'sex': 'boy'}, {'name': 'Nike', 'age': 18, 'class_number': 'A', 'sex': 'boy'}, {'name': 'Lily', 'age': 18, 'class_number': 'A', 'sex': 'girl'}, {'name': 'Adem', 'age': 18, 'class_number': 'C', 'sex': 'boy'}, {'name': 'HanMeiMei', 'age': 18, 'class_number': 'B', 'sex': 'girl'}, {'name': 'Marry', 'age': 16, 'class_number': 'A', 'sex': 'girl'}]
# >>> []
result = student_info.search_users(name='')
print(result)
以上即为关于 Python 异常处理中断言(assert)的详细内容解析。如需获取更多关于 Python 异常处理的资料,请持续关注本站发布的其他相关文章。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









