python中的断言是什么意思_一日一技:python中的断言

本文介绍了Python中的断言用于程序内部检查,帮助开发者在调试阶段发现错误。断言在条件不满足时引发AssertionError,但其在优化模式下可能失效,不应依赖断言进行数据验证。文章提醒开发者避免使用断言处理运行时异常,而应使用常规异常处理,以确保代码的安全性和健壮性。
摘要由CSDN通过智能技术生成

一、使用python中的断言来自动检测python程序中的错误,让程序更加可靠且更易于调试

从根本上来说,python中的断言语句是一种调试工具,用来测试某个断言条件,如果断言条件为True,则程序将继续正常执行;但如果断言条件为假False,则会引发AssertionError异常并显示相关的错误消息。

示例:

假设你需要使用python构建在线商城,为了添加打折优惠功能,你编写了下面这个apply_discount函数:

def apply_discount(product, discount):

price = int(product['price'] * (1 - discount))

assert 0 <= price <= product['price'] # 断言

return price

注意到assert语句了吗?这条语句确保在任何情况下,通过该函数计算的折后价格不低于0,也不会高于产品原价。

下面创建一个示例产品,一双价格为1000元的鞋子,现在如果为这双鞋打五折,则价格应该变为500,对该函数进行测试:

def apply_discount(product, discount):

price = int(product['price'] * (1 - discount))

assert 0 <= price <= product['price']

return price

if __name__ == "__main__":

shoes = {

"name": "鞋子",

"price": 1000,

}

price = apply_discount(shoes, 0.5)

print(price)

还不错,接着我们再尝试使用一些无效的折扣,比如200%的”折扣“会让商家向顾客付钱:

从上面的信息可以看到,当尝试使用无效的折扣时,程序会停止并触发一个AssertionError。发生这种情况是因为200%的折扣违反了在apply_discount函数中设置的断言条件,从异常栈的跟踪信息中还能得知断言验证失败的具体位置。

二、为什么不用普通的异常来处理?

断言是为了告诉开发人员程序中发生了不可恢复的错误,对于可以预料的错误(如未找到相关文件),用户可以予以纠正或重试,断言并不是为此而生的。

如果程序没有bug,那么这些断言条件永远也不会触发,但如果违反了断言条件,程序就会崩溃并报告断言错误,告诉开发人员究竟违反了哪个“不可能”的情况,这样可以更轻松的追踪和修复程序中的bug。python中的断言语句是一种调试辅助功能,不是用来处理运行时错误的机制,使用断言的目的是让开发人员更快速的找到可能导致bug的根本原因,除非程序中存在bug,否则绝不会抛出断言错误。

三、assert语法及使用注意事项

语法:

assert <断言判断条件> [,"错误提示消息"]

其中的错误提示消息是可选的,如果加了错误提示消息,则会在抛出异常时,同异常消息一同展示,如:

注意事项:

在Python中使用断言时,需要注意,第一:断言会给应用程序带来安全风险和bug;第二:容易写出很多无用的断言语句。

1、不用使用断言验证数据

在python中使用断言时要注意的一个重点是,若在命令行中使用-o和-oo标识,或修改CPython中的PYTHONOPTIMIZE环境变量,都会全局禁用断言。此时所有的断言语句都会无效,程序会直接略过而不处理断言,因此不会执行任何条件表达式,因此使用断言语句来快速验证输入数据非常危险。

下面用一个简单的例子说明这个问题,前面一样,假设使用Python构建一个在线商城,代码中有一个函数会根据用户的请求来删除产品,于是写下这样的实现:

def delete_product(prod_id, user):

assert user.is_admin(), "Must be admin."

assert store.has_product(prod_id), "Unknown product."

store.get_product(prod_id).delete()

仔细看这个函数,如果断言被禁用后会发生什么?这个仅有三行代码的函数示例存在两个严重的问题:

(1)使用断言语句检查管理员权限很危险,如果在Python解释器中禁用了断言,这行代码则会变为空操作,不会执行权限检查,之后任何用户都可以删除产品,这可能会引发安全问题,攻击者可能会借此摧毁或严重破会在线商城中的数据。

(2)禁用断言后会跳过has_product()检查,这意味着可以使用无效的产品ID调用get_product(),这可能会导致更严重的bug,具体情况取决于程序的编写方式,在最糟糕的情况下,有人可以借此对商城发起拒绝服务攻击。例如:如果尝试删除未知产品会导致商城应用程序崩溃,那么 攻击者就可以发送大量无效的删除请求让程序无法正常工作。

那么如何避免这些问题呢?答案是绝对不要使用断言来验证数据,而是使用常规的 if 语句验证,并在必要的时候触发验证异常,如下所示:

def delete_product(prod_id, user):

if not user.is_admin():

raise AuthError("Must be admin.")

if not store.has_product(prod_id):

raise ValueError("Unknown product.")

store.get_product(prod_id).delete()

修改后的示例还有个好处,即代码不会触发通用的AssertionError异常,而是触发与语义相关的异常,如ValueError或AuthError。

2、永不失败的断言

开发人员很容易就会添加许多总是为True的python断言,因此这些语句毫无用处,永远不会触发异常。

四、总结

尽管有这些需要注意的事项,但Python的断言依然是功能强大的调试工具,了解断言的工作方式及其使用场景有助于编写更易于维护和调试的Python程序,学习断言有助于将个人的python知识提升到新的水平。

关键要点:python断言语句是一种测试某个条件的调试辅助功能,可作为程序的内部自检

断言应该只用于帮助开发人员识别bug,它不是用于处理运行时异常的机制

设置解释器可全局禁用断言

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值