码迷,mamicode.com
首页 > 编程语言 > 详细

Python 调试

时间:2016-07-14 07:14:21      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:python   logging   assert   pdb   set_trace   

1.1   调试

1.1.1   print()

shellplsql中我都习惯用echodbms_output.put_line输出变量,查看变量异常。

python程序中,可用print()函数展示变量。

缺点就是,调试完成后,需编辑源代码删除多余的print函数。

这里不做实例演示。

1.1.2   assert

凡是可用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

1.1.3   logging

可以简单理解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无论有没有错误抛出,都会输出记录

指定记录信息的级别:debuginfowarningerror

1.1.4   pdb

启动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

1.1.5   pdb.set_trace()

这种方法也是调用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()

在调试过程中,逐步改变断点的位置,从而缩小错误的范围。

1.1.6   终极武器

难道logging才是调试代码的终极武器,待议。


本文出自 “90SirDB” 博客,请务必保留此出处http://90sirdb.blog.51cto.com/8713279/1826214

Python 调试

标签:python   logging   assert   pdb   set_trace   

原文地址:http://90sirdb.blog.51cto.com/8713279/1826214

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!