善用Assert-你应该知道的Python技巧

写程序遇到bug在所难免,今天我们说一个使用的debug技巧-Assert语句。

首先打开Assert官方文档。我们可以看到:

1
assert_stmt ::= "assert" expression1 ["," expression2]

默认情况下,assert expression1等价于

1
2
3
if __debug__:
if not expression1:
raise AssertionError

意思是:如果expression1为真,则不会报错,如果expression1为假,则会抛出AssertionError异常
可选情况下, assert expression1, expression2等价于

1
2
3
if __debug__:
if not expression1:
raise AssertionError(expression2)

意思是:如果expression1为真,则不会报错,如果expression1为假,则会抛出则会
抛出expression2作为debug的信息。

举个实例:

如果你想要开发一个购物网站,其中会有打折活动,如何设计打折逻辑?

你可以这样做:

1
2
3
4
5
6
book = {"name": "Python tutorials", "price": "100"}

def do_discount(product, discount):
price = int(product['price'] * (1.0 -discount))
assert 0 <= price <= price['price']
return price

调用该方法

1
do_discount(book, 0.25)

得到结果: 75

如果

1
do_discount(book, 2.0)

则会

1
2
3
Traceback (most recent call last):
...
AssertionError

需要注意的两个问题:

1. 不要用asserts做数据验证

1
2
3
4
5
6
# Don't do this

def delete_product(prod_id, user):
assert user.is_admin(), "Must be admin"
assert store.has_prodcut(prod_id), "Unknown product")
store.get_product(prod_id).delete()

为什么不能这样做?大家可以思考一下,给我留言。

你可以这样做,

1
2
3
4
5
6
def delete_product(product_id, user):
if not user.is_admin():
raise AuthError("Must be admin to delete")
if not store.has_product(product_id):
raise ValueError("Unknown product id")
store.get_product(product_id).delete()

2. 这样的assert从不会fail

1
assert(1 == 2, "This should fail")

欢迎关注**数据之禅**.

Sumer Zhang wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客。