Python随手笔记(十)--------(2)

调试

每个程序能一次写完并正常运行的概率基本不超过1%,因为总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。
第一种方法简单直接粗暴有效,就是用print()把可能有问题的变量打印出来看看:

def foo(s):
    n = int(s)
    print('>>> n = %d' % n)
    return 10 / n

def main():
    foo('0')

main()

输出结果:

>>> n = 0
Traceback (most recent call last):
  File "F:/python文件/tiaoshi/__init__.py", line 9, in <module>
    main()
  File "F:/python文件/tiaoshi/__init__.py", line 7, in main
    foo('0')
  File "F:/python文件/tiaoshi/__init__.py", line 4, in foo
    return 10 / n
ZeroDivisionError: division by zero

当然这种方法存在着弊端,运行结果中包含很多没有意义的信息,所以,出现了第二种方法:

断言

凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:

def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n

def main():
    foo('0')

main()

assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。

如果断言失败,assert语句本身就会抛出AssertionError:

 assert n != 0, 'n is zero!'
AssertionError: n is zero!

logging

把print()替换为logging是第3种方式,和assert比,logging不会抛出错误,而且可以输出到文件:

>>> import logging
>>> s = '0'
>>> n = int(s)
>>> logging.info("n=%d"%n)
>>> print(10/n)

但我们发现输出结果却很简单草率:

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    print(10/n)
ZeroDivisionError: division by zero

然后我们加一句配置再次尝试:
logging.basicConfig(level=logging.INFO)

INFO:root:n = 0
Traceback (most recent call last):
  File "err.py", line 8, in <module>
    print(10 / n)
ZeroDivisionError: division by zero

这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。

logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。

发布了37 篇原创文章 · 获赞 42 · 访问量 4490

猜你喜欢

转载自blog.csdn.net/qq_43337175/article/details/104629280