assert 的合理使用,可以增加代码的健壮度,同时也方便了程序出错时开发人员的定位排查。

什么是 assert?

Python 的 assert 语句,可以说是一个 debug 的好工具,主要用于测试一个条件是否满足。如果测试的条件满足,则什么也不做,相当于执行了 pass 语句;如果测试条件不满足,便会抛出异常 AssertionError,并返回具体的错误信息(optional)。它的具体语法是下面这样的:

assert 1 == 2,  'assertion is wrong'

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

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

__debug__是一个常数,解释器开始运行时就已经决定了__debug__True,当运行时加上-O这个选项,__debug__False,导致所有的 assert 语句都失效。需要注意的是,直接对常数__debug__赋值是非法的。

assert 的用法

示例 1,用来检查折后价格,这个值必须大于等于 0、小于等于原来的价格,否则就抛出异常

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

示例 2,规定销售数目必须大于 0,这样就可以防止后台计算那些还未开卖的专栏的价格

def calculate_average_price(total_sales, num_sales):
assert num_sales > 0, 'number of sales should be greater than 0'
return total_sales / num_sales

示例 3,input必须是list

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

assert错误示例

示例 1,极客时间规定,必须是 admin 才能删除专栏,并且这个专栏课程必须存在。然而当执行时增加-O选项,会导致任何用户都可以删除专栏。

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 即使被关闭也不能影响原本的代码功能和逻辑。可以采用下面这种写法。

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)

示例 2,如果你想打开一个文件,进行数据读取、处理等一系列操作,那么下面这样的写法,显然也是不正确的。

def read_and_process(path):
assert file_exist(path), 'file must exist'
with open(path) as f:
...

因为 assert 的使用,表明你强行指定了文件必须存在,但事实上在很多情况下,这个假设并不成立。另外,打开文件操作,也有可能触发其他的异常。所以,正确的做法是进行异常处理,用 try 和 except 来解决:

def read_and_process(path):
try:
with open(path) as f:
...
except Exception as e:
...

总的来说,assert 并不适用 run-time error 的检查。比如你试图打开一个文件,但文件不存在;再或者是你试图从网上下载一个东西,但中途断网了了等等,这些情况下,还是应该参照我们前面所讲的错误与异常的内容,进行正确处理。

最新文章

  1. 为 Sublime Text 3059 配置 PHP 编译环境
  2. echarts之tooltip-position
  3. SQL Server 2008 表变量 临时表
  4. angular学习input输入框筛选
  5. python3-day2-python基础2
  6. oracle11g dataguard 完全手册
  7. JavaScript 中 的prototype和__proto__
  8. Javascript高级程序设计——函数声明与函数表达式的区别
  9. 西川善司【神秘海域(Uncharted)】的图形分析
  10. JQuery中的push和join
  11. ASP.NET 不同页面之间传值
  12. WPF 保存文件
  13. Visual Studio 2013 无法启动 IIS Express 的解决办法
  14. oracle使用还原段的目的和还原数据的管理方法及还原段的类型
  15. Python装饰器学习(九步入门)
  16. Arduino语言简介
  17. 一天带你入门到放弃vue.js(三)
  18. MATLAB:图像滤波,绝对值差(filter2,imabsdiff函数)
  19. jsp的九大内置对象及作用
  20. HDU5952 Counting Cliques (暴力深搜+剪枝) (2016ACM/ICPC亚洲赛区沈阳站 Problem E)

热门文章

  1. WeChat-SmallProgram:自定义select下拉选项框组件
  2. linux svn 批量添加
  3. 如何找回QQ聊天记录、语音、图片?
  4. Unix 下 使用 RVM 管理 Ruby 和 gem
  5. 实验十三 MySQL多用户事务管理
  6. STM32F103ZET6独立看门狗
  7. JavaScript-原始值和引用值
  8. 部署mysql主从同步
  9. ASP.NET Core中的Controller
  10. Hadoop (六):MapReduce基本使用