python的调试
调试 程序能一次写完并正常执行的概率很小。总会有各种各样的bug需要修正。
有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时
哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。 第一种方法:print
简单直接粗暴有效,就是用print()把可能有问题的变量打印出来看看: def foo(s):
n = int(s)
print(">>>n = %d" % n)
return 10 / n def main():
foo("") main() 输出结果: >>>n = 0
Traceback (most recent call last):
File "C:/Python36/test.py", line 9, in <module>
main()
File "C:/Python36/test.py", line 7, in main
foo("")
File "C:/Python36/test.py", line 4, in foo
return 10 / n
ZeroDivisionError: division by zero 用print()最大的坏处是将来还得删除它,想想程序里到处都是print(),运行结果也会包含很多垃圾信息。
所以,我们又有第二种方法。 第二种方法:断言 凡是用print()来辅助查看的地方,都可以用断言(assert)来代替:
def foo(s):
n = int(s)
assert n != 0, "n is zero!"
return 10 / n def main():
foo("") main() assert的意思是,表达式 n!=0 应该是True,否则根据程序运行的逻辑,后面的代码肯定会出错。
如果断言失败,assert语句本身就会抛出AssertionError: Traceback (most recent call last):
File "C:/Python36/test.py", line 9, in <module>
main()
File "C:/Python36/test.py", line 7, in main
foo("")
File "C:/Python36/test.py", line 3, in foo
assert n != 0, "n is zero!"
AssertionError: n is zero! 如果程序中到处充斥着assert,和print()相比也好不到哪去。
不过启动python解释器可以用-o参数来关闭assert:
$ python3 -O err.py
Traceback (most recent call last):
...
ZeroDivisionError: division by zero 关闭后,你可以把所有的assert语句当成pas来看。 第三种方法:logging
把print()替换为logging是第三种方式,和assert比,logging不会抛出错误,而且可以输出到文件。 import logging s = ""
n = int(s)
logging.info("n = %d" % n)
print(10 / n) 输出结果:
Traceback (most recent call last):
File "C:/Python36/test.py", line 6, in <module>
print(10 / n)
ZeroDivisionError: division by zero
>>> logging.info()就可以输出一段文本。
运行,发现除了ZeroDivisionError, 没有任何信息。 怎么回事呢? 别急,在import logging 之后添加一行配置再试试
import logging
logging.basicConfig(level = logging.INFO) s = ""
n = int(s)
logging.info("n = %d" % n)
print(10 / n) 输出结果:
INFO:root:n = 0
Traceback (most recent call last):
File "C:/Python36/test.py", line 7, in <module>
print(10 / n)
ZeroDivisionError: division by zero 看到输出了吧,这就是使用logging的好处,它允许你指定记录信息的级别
有debug,info,warning,error等几个级别。
当我们指定level = INFO时,logging.debug就不起作用了。
同理,指定level = WAENING后,debug和info就不起作用了。
这样一来,拟具可以放心地除数不同级别的I想你,也不用删除,最后统一控制输出哪个级别的信息。
logging的另一个好处就是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。 第四种方法:pdb
第四种方式是移动python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。
我们先来准备好程序: s = ""
n = int(s)
print(10 / n) $ python3 -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()
-> s = '' 然后逐行输入代码检查。
这种通过pdb在命令行调试的方法理论上是万能的,但是实在太麻烦了。 IDE 如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有PyCharm: http://www.jetbrains.com/pycharm/ 另外,Eclipse加上pydev插件也可以调试Python程序。 总结: 写程序最痛苦的事情莫过于调试,程序往往会以你意想不到的流程来运行,你期待执行的语句其实根本没有执行,这时候,就需要调试了。 虽然用IDE调试起来比较方便,但是最后你会发现,logging才是终极武器。
python的调试的更多相关文章
- python基础——调试
python基础——调试 程序能一次写完并正常运行的概率很小,基本不超过1%.总会有各种各样的bug需要修正.有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是 ...
- 在ubunut下使用pycharm和eclipse进行python远程调试
我比较喜欢Pycharm,因为这个是JetBrains公司出的python IDE工具,该公司下的java IDE工具--IDEA,无论从界面还是操作上都甩eclipse几条街,但项目组里有些人使用e ...
- FAQ:Python 断点调试
Python程序调试:断点调试是必须有的功能,以Pycharm开发工具为例: 一.理论知识: 1. step into(F7)就是单步执行,遇到子函数就进入并且继续单步执行: 2 step over ...
- python pdb调试以及sublime3快捷键设置
python pdb调试以及sublime3快捷键设置 pdb调试 如果对gdb比较熟悉的话,pdb就很容易上手.以一个demo快速了解常用的调试命令. def test(a): while True ...
- python --端点调试
python端点调试 左边三角:快速跳到下一个端点 下箭头:单不调试 斜向下箭头:跳到函数内部执行代码
- 使用IntelliJ IDEA进行Python远程调试的需求(未完)
使用IntelliJ IDEA进行Python远程调试的需求(未完) 在研究深度学习Machlearning时,有时候需要借助ubuntu搭建的tensorflow环境,另外也有越来越多的运算程序只能 ...
- python基础===利用PyCharm进行Python远程调试(转)
原文链接:利用PyCharm进行Python远程调试 背景描述 有时候Python应用的代码在本地开发环境运行十分正常,但是放到线上以后却出现了莫名其妙的异常,经过再三排查以后还是找不到问题原因,于是 ...
- python错误调试print、assert、logging、pdb、pdb.set_trace()
世界人都知道,程序总会有bug存在.复杂点的bug一般人不能一眼看出,这就一要一套调试程序的手段. 方法一:使用print()函数直接打印: >>> def foo(s): ... ...
- python - 代码调试的好帮手sys._getframe()
python 的调试,令人非常忧伤,通过将输出路径打印的方式,可以提高很大的方便性: import sys #coding=utf-8 def get_cur_info(): print sys._g ...
随机推荐
- 使用angular-ui-router替代ng-router
angular框架自身提供的ng-route在一定程度上满足了我们的需求,但是他只针对于单视图,比如点击一个link跳转到另一个视图,但是在实际业务中,需要一个状态对应的视图中还包含其他的视图,或者一 ...
- Java多线程JUC
1. volatile 关键字 多线程访问的时候,一个比较严重的问题就是内存不可见,其实在内存访问的时候每一个线程都有一个自己的缓冲区,每次在做修改的时候都是从主存取到数据,然后放到自己的缓冲区中,在 ...
- MYSQL数据库学习六 索引的操作
6.1 索引 由于数据存储在数据库表中,所以索引是创建在数据库表对象上的,由表中的一个或多个字段生成的键组成,这些键存储在数据结构(B-树或哈希表)中,通过索引可以快速有效地查找与键值相关联的字段.根 ...
- newInstance()和new()的区别
转载:http://www.jobui.com/mianshiti/it/java/7148/ newInstance: 弱类型.低效率.只能调用无参构造.new: 强类型.相对高效.能调用任何pub ...
- Algorithm --> 字母重排
字母重排 输入一个字典(用***结尾),然后再输入若干单词.没输入一个单词w,都需要在字典中找出所有可以用w的字幕重排后得到的单词,并按照字典序从小到大的顺序在一行中输出,如果不存在,输出“:(”.单 ...
- #Python3.6.2(32位) pip安装 和 pygame 环境配置
#首先确认电脑已经安装python ,可通过在命令行下 执行 python --version确认. 1. 到 https://pypi.python.org/pypi/setuptools/ 下载 ...
- PHP-CGI,FASTcgi,php-fpm,之间的关系?
刚开始对这个问题我也挺纠结的,看了<HTTP权威指南>后,感觉清晰了不少.首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. ...
- 实现Windows程序的数据绑定
1.创建DataSet对象 语法: DataSet 数据集对象 =new DataSet("数据集的名称字符串"); 语法中的参数是数据集的名称字符串,可以有,也可以没有.如 ...
- C语言指针作业
一.PTA实验作业 题目1:6-5 判断回文字符串 1. 本题PTA提交列表 2. 设计思路 3.代码截图 4.本题调试过程碰到问题及PTA提交列表情况说明. 第一次做的时候我j直接等于count,其 ...
- Beta版本敏捷冲刺每日报告——Day2
1.情况简述 Beta阶段第二次Scrum Meeting 敏捷开发起止时间 2017.11.3 08:00 -- 2017.11.3 22:00 讨论时间地点 2017.11.3晚9:00,软工所实 ...