【Python 基础篇】Python中的assert 断言

assert语句用于测试某个条件,如果条件为假,则会抛出AssertionError异常。在正常模式下,__debug__为True,assert会执行;在优化模式(-O选项)下,assert会被忽略。assert常用于代码调试和确保函数参数或预设条件的正确性。错误提示可以自定义,方便定位问题。在后验条件检查中,应使用异常处理,以便提供更详细的错误信息并控制程序流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Assert 语法

assert 语句的语法结构为:

assert <表达式>
assert <表达式>, <错误提示语>

等价于:

if __debug__:
    if not expression: raise AssertionError

# 以及
if __debug__:
    if not expression1: raise AssertionError(expression2)

以上等价形式假定 __debug__ 和 AssertionError 指向具有指定名称的内置变量。在当前实现中,内置变量 __debug__ 在正常情况下为 True,在请求优化时为 False (对应命令行选项为 -O)。 如果在编译时请求优化,当前代码生成器不会为 assert 语句发出任何代码。

请注意不必在错误信息中包含失败表达式的源代码;它会被作为栈追踪的一部分被显示。

赋值给 __debug__ 是非法的,该内置变量的值会在解释器启动时确定。

以下脚本:

# test.py
print(__debug__)
assert 0 > 1

当执行脚本 python test.py 时,__debug__ 为 True,断言语句抛出 AssertionError 异常。

如果执行脚本 python -O test.py 时,__debug__ 为 False,断言未执行,代码无异常。

实用举例

以下是为了方便理解的一些示例:

# 正常
assert 10
assert True
assert 1 > 0 

# 抛出异常
assert 0
assert False
assert 1 > 2
assert len(range(3)) > 3
assert range(3) == [0,1,2]
# AssertionError: 

# 提示语
assert 1==2, '1 不等于 2'
# AssertionError: 1 不等于 2

assert 1/0 # 此处不是断言的作用,表达式本身报错
# ZeroDivisionError: division by zero

当 assert 语句后的表达式值为真时,程序继续执行;否则报 AssertionError 错误,程序停止执行,及时止损。

经典案例

检查先验条件使用断言,检查后验条件使用异常。就是说,在执行代码前要检查就是断言,在执行代码过程中,用异常。

以下是一些使用场景示例。

判断输入是否正确

判断输入数字符合要求,否则报错。

number = int(input('请输入小于10的数字'))

# 断言
assert number < 10
print("输入正确!", number)

Python 版本判断

不支持 Python 版本判断:

import sys
assert sys.version_info.major==2, '不支持 Python 2'
# AssertionError: 不支持 Python 2

函数参数合法性检测

定义一个加法计算,检测数据类型:

def add(x, y):
    assert isinstance(x, int|float), 'x数字格式不对!'
    assert isinstance(y, int|float), 'y数字格式不对!'
    return x + y

add(1,1.2) # 2.2
add('1', 1)
# AssertionError: x数字格式不对!

你可以写一个除法,让除数不能为 0。

读取文件函数

read_file 函数在被调用执行后,依然需要满足一定条件,比如 file_path 所指定的文件需要是存在的,并且当前用户有权限读取该文件,这些条件称为后验条件,对于后验条件的检查,我们需要使用异常来处理。

def read_file(file_path):
    assert isinstance(file_path, str)
    if not check_exist(file_path):
        raise FileNotFoundError()
    if not has_privilege(file_path):
        raise PermissionError()

文件不存在和没有权限,这两种情况并不属于代码 bug,是代码逻辑的一部分,上层代码捕获异常后可能会执行其他逻辑,因此我们不能接受这部分代码在生产环境中被忽略。并且,相比于 assert 语句只能抛出 AssertionError,使用异常可以抛出更细致的错误,方便上层代码针对不同错误执行不同的逻辑。

其他

有时候你可能看到这样的写法:

assert(1>1)
# AssertionError:

assert(1>1), '1不大于1'
# AssertionError: 1不大于1

不要以为 assert 是内置函数,其实它的合规写法是:

assert 1>1, '1不大于1'

只不过给 assert 后的表达式加了圆括号而已。

这其实也和 Python 允许函数名后的调用括号可以有多个空格的语法一样:

def func():
    print(123)

func   ()
# 123

关键字语句后也可以用圆括号包起来,而不用空格:

if(1+1>0):
    print(1)
# 1

这是人们经常使用括号进行符合 PEP 8 的隐式行延拓。

以上写法容易引起混淆,因此,我们要避免以上的写法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值