标签:python logging assert pdb set_trace
在shell和plsql中我都习惯用echo和dbms_output.put_line输出变量,查看变量异常。
在python程序中,可用print()函数展示变量。
缺点就是,调试完成后,需编辑源代码删除多余的print函数。
这里不做实例演示。
凡是可用print()函数来查看的地方,都可用assert。
>>> def foo(s):
... n = int(s)
... assert n != 0, ‘n is zero.‘ -- n != 0为真,继续往下运行,否则抛出字符串异常
... return 10 / n
...
>>> def main():
... foo(‘0‘)
...
>>> main()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in main
File "<stdin>", line 3, in foo
AssertionError: n is zero.
启动Python解释器时可以用-O参数(大写字母O)来关闭assert。
例如python -O assert.py
[root@daidai python]# cat assert.py
#!/usr/bin/python
# -*- coding:utf-8 -*-
def foo(s):
n= int(s)
assert n != 0, ‘n is zero!‘
return 10 / n
def main():
foo(‘0‘)
main()
[root@daidai python]# python -O assert.py
Traceback (most recent call last):
File "assert.py", line 11, in <module>
main()
File "assert.py", line 9, in main
foo(‘0‘)
File "assert.py", line 6, in foo
return 10 / n
ZeroDivisionError: division by zero
关闭之后所有assert语句等价于pass
可以简单理解logging为记录的意思,logging不会抛出错误。
[root@daidai python]# cat err_log_level.py
import logging
logging.basicConfig(level=logging.INFO)
s = ‘1‘
n = int(s)
logging.info(‘n = %d‘ %n)
print(10 / n)
[root@daidai python]# pythonerr_log_level.py
INFO:root:n = 1 -- logging.info输出后面的信息
10.0
[root@daidai python]# cat err_log_level.py
import logging
logging.basicConfig(level=logging.INFO)
s = ‘0‘
n = int(s)
logging.info(‘n = %d‘ %n)
print(10 / n)
[root@daidai python]# pythonerr_log_level.py
INFO:root:n = 0
Traceback (most recent call last):
File "err_log_level.py", line 6, in <module>
print(10 / n)
ZeroDivisionError: division by zero
logging无论有没有错误抛出,都会输出记录。
指定记录信息的级别:debug,info,warning,error
启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。
[root@daidai python]# python -m pdb err.py --启用pdb
> /root/python/err.py(4)<module>()
-> def foo(s):
(Pdb) l
1 #!/bin/bash/python
2 # -*- coding:utf-8 -*-
3
4 -> def foo(s):
5 return 10 / int(s)
6
7 def bar(s):
8 return foo(s) * 2
9
10 def main():
11 bar(‘0‘)
(Pdb) n
> /root/python/err.py(7)<module>()
-> def bar(s):
(Pdb) l
2 # -*- coding:utf-8 -*-
3
4 def foo(s):
5 return 10 / int(s)
6
7 -> def bar(s):
8 return foo(s) * 2
9
10 def main():
11 bar(‘0‘)
12
(Pdb) n
>/root/python/err.py(10)<module>()
-> def main():
(Pdb) l
5 return 10 / int(s)
6
7 def bar(s):
8 return foo(s) * 2
9
10 -> def main():
11 bar(‘0‘)
12
13 main()
14
[EOF]
(Pdb) n
>/root/python/err.py(13)<module>()
-> main()
(Pdb) l
8 return foo(s) * 2
9
10 def main():
11 bar(‘0‘)
12
13 -> main()
14
[EOF]
(Pdb) n
ZeroDivisionError: division by zero
> /root/python/err.py(13)<module>()
-> main()
(Pdb)
交互式命令说明:
l:查看代码;
n:执行下一步;
p:查看变量,p 变量名;
q:退出pdb。
这种方法也是调用pdb,只是不需单步调用,相当于断点。
[root@daidai python]# cat err.py
#!/bin/bash/python
# -*- coding:utf-8 -*-
import pdb
def foo(s):
return 10 / int(s)
pdb.set_trace()
def bar(s):
return foo(s) * 2
pdb.set_trace()
def main():
bar(‘0‘)
pdb.set_trace()
main()
[root@daidai python]# python err.py
> /root/python/err.py(9)<module>()
-> def bar(s):
(Pdb) l
4 import pdb
5
6 def foo(s):
7 return 10 / int(s)
8 pdb.set_trace() --遇到第一个断点程序就停止运行
9 -> def bar(s):
10 return foo(s) * 2
11 pdb.set_trace()
12 def main():
13 bar(‘0‘)
14 pdb.set_trace()
(Pdb) n
> /root/python/err.py(11)<module>()
-> pdb.set_trace()
(Pdb) p s
*** NameError: name ‘s‘ is not defined
(Pdb) n
>/root/python/err.py(12)<module>()
-> def main():
(Pdb) n
>/root/python/err.py(14)<module>()
-> pdb.set_trace()
(Pdb) l
9 def bar(s):
10 return foo(s) * 2
11 pdb.set_trace()
12 def main():
13 bar(‘0‘)
14 -> pdb.set_trace()
15 main()
16
[EOF]
(Pdb) n
>/root/python/err.py(15)<module>()
-> main()
(Pdb) n
ZeroDivisionError: division by zero
>/root/python/err.py(15)<module>()
-> main()
在调试过程中,逐步改变断点的位置,从而缩小错误的范围。
难道logging才是调试代码的终极武器,待议。
本文出自 “90SirDB” 博客,请务必保留此出处http://90sirdb.blog.51cto.com/8713279/1826214
标签:python logging assert pdb set_trace
原文地址:http://90sirdb.blog.51cto.com/8713279/1826214