什么是assert?

Python 的 assert 语句是一个 debug 的好工具,主要用于测试一个条件是否满足。如果测试的条件满足,则什么也不做,相当于执行了 pass 语句;

如果测试条件不满足,便会抛出异常 AssertionError, 并返回具体的错误信息(optional)。

它具体的语法是下面这样的:

assert_stmt ::= "assert" expression ["," expression]

我们先来看一个简单形式的 assert expression, 比如下面这个例子:

assert 1 == 2

它就相当于下面两行代码:

if __debug__:
if not expression: raise AssertionError

再来看 assert expression1, expression2的形式,比如下面这个例子:

assert 1 == 2, 'assertion is wrong'

它就相当于下面这两行代码:

if __debug__:
if not expression1: raise AssertionError(expression2)

这里的__debug__是一个常数。如果Python程序执行时附带了-O这个选项,比如Python test.py -O, 那么程序中所有的 assert 语句都会失效,常数

__debug__便为False;反之__debug__则为True。

直接对常数__debug__赋值时非法的,因为它的值在解释器开始运行时就已经决定了,中途无法改变。

一定记住,不要在使用 assert 时加入括号,比如下面这个例子:

assert(1 == 2, 'This should fail')
"""
SyntaxWarning: assertion is always true, perhaps remove parentheses?
assert(1 == 2, 'This should fail')
"""

总的来说,assert 在程序中的作用,是对代码做一些内部(internal)的自检(self-check)。使用 assert,就表示你很确定。这个条件一定会发生

或者一定不会发生。

assert使用

假设要做一个促销活动,如下面的apply_discount()函数,要求输入为原来的价格和折扣,输出的是折后的价格。

def apply_discount(price, discount):
updated_price = price * (1 - discount)
assert 0 <= updated_price <= price, 'price should be greater or equal to 0 and less or equal to original price'
return updated_price

可以看到,在计算新价格的后面,我们还写了一个assert语句,用来检查折后价格,这个必须大于等于0、小于等于原来的价格,否则就抛出异常。

assert 常见用法

def func(input):
assert isinstance(input, list), 'input must be type of list'
# 下面的操作都是基于前提:input 必须是 list
if len(input) == 1:
...
elif len(input) == 2:
...
else:
...

这里的func中各种逻辑的前提是input是一个list,所以可以在开头加一句assert,防止程序出错。

assert错误使用

数据库的删除操作

def delete_course(user, course_id):
assert user_is_admin(user), 'user must be admin'
assert course_exist(course_id), 'course id must exist'
delete(course_id)

不可以用assert, 因为assert可以通过-O取消,这样随便一个用户都可以删除,而且不管这个id是否存在都可以强制执行删除。正确做法:

def delete_course(user, course_id):
if not user_is_admin(user):
raise Exception('user must be admin')
if not course_exist(course_id):
raise Exception('coursde id must exist')
delete(course_id)

最新文章

  1. android view : 动画
  2. Swift3.0语言教程替换子字符串
  3. yii2高级版账号密码问题
  4. ODBC错误处理
  5. 最长公共上升子序列(LICS) 模板
  6. 【POJ 3623】 Best Cow Line, Gold (后缀数组)
  7. poj 1940 Wine Trading in Gergovia_贪心
  8. Linux下的 &gt;, &gt;&gt;, &lt;, ps, |, grep, /dev/null
  9. mongoDB创建windows服务启动解决
  10. 二十三. Python基础(23)--经典类和新式类
  11. openvas安装和基本使用
  12. HttpClient Fluent API 高并发优化
  13. 免费CDN公共库——网站提速 静态资源库
  14. Java 8新特性探究(二)深入解析默认方法
  15. linux上搭建redis
  16. 获取Javascript 滚动条距离顶部的距离(兼容IE6+,火狐,谷歌,其它没测)
  17. OAuth 白话简明教程 5.其他模式
  18. oj1089-1096总结(输入输出练习)
  19. 【刷题】BZOJ 1211 [HNOI2004]树的计数
  20. 【UVA 11077】 Find the Permutations (置换+第一类斯特林数)

热门文章

  1. REST架构中的HTTP动词
  2. Python基础 第三章 使用字符串(1)精简版
  3. tomcat 发布的web项目不在webapps目录下
  4. shell习题第15题:看数字找规律
  5. java7:核心技术与最佳实践读书笔记——字节代码格式
  6. LeetCode:596.超过5名学生的课
  7. 转载:Web安全X-FRAME-OPTIONS 出现两个或多个的原因
  8. 第五章、前端之JQuery
  9. 【Day2】4.第三方模块的安装与使用
  10. Mysql系列-性能优化神器EXPLAIN使用介绍及分析