python基础——调试

  

  程序能一次写完并正常运行的概率很小,基本不超过1%。总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。

  第一种方法简单直接粗暴有效,就是用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):
...
ZeroDivisionError: integer division or modulo by zero

  用print()最大的坏处是将来还得删掉它,想想程序里到处都是print(),运行结果也会包含很多垃圾信息。所以,我们又有第二种方法。

断言

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

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

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

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

    

  程序中如果到处充斥着assert,和print()相比也好不到哪去。不过,启动Python解释器时可以用-O参数来关闭assert

    

  关闭后,可以把所有的assert语句当成pass来看。

logging

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

import logging

s = ''
n = int(s)
logging.info('n = %d' % n)
print(10 / n)

  logging.info()就可以输出一段文本。运行,发现除了ZeroDivisionError,没有任何信息。怎么回事?

    

  别急,在import logging之后添加一行配置再试试:

import logging
logging.basicConfig(level=logging.INFO)

  看到输出了:

    

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

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

pdb

  第4种方式是启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。我们先准备好程序:

s = ''
n = int(s)
print(10 / n)

  然后启动:

    

  以参数-m pdb启动后,pdb定位到下一步要执行的代码-> s = '0'。输入命令l来查看代码:

    

  输入命令n可以单步执行代码:

    

  任何时候都可以输入命令p 变量名来查看变量:

    

  输入命令q结束调试,退出程序:

(Pdb) q

  这种通过pdb在命令行调试的方法理论上是万能的,但实在是太麻烦了,如果有一千行代码,要运行到第999行得敲多少命令啊。还好,我们还有另一种调试方法。

  

pdb.set_trace()

  这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点:

import pdb

s = ''
n = int(s)
pdb.set_trace() # 运行到这里会自动暂停
print(10 / n)

  运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行:

    

  这个方式比直接启动pdb单步调试效率要高很多,但也高不到哪去。

IDE

  如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有PyCharm:

  http://www.jetbrains.com/pycharm/

  另外,Eclipse加上pydev插件也可以调试Python程序。

小结

  写程序最痛苦的事情莫过于调试,程序往往会以你意想不到的流程来运行,你期待执行的语句其实根本没有执行,这时候,就需要调试了。

  虽然用IDE调试起来比较方便,但是最后你会发现,logging才是终极武器

参考源码:

  do_assert.py:

 #python 调试   示例
#断言assert示例
#2016-8-31 20:25:15
#MengmengCoding
# -*- coding: utf-8 -*- def foo(s):
n=int(s)
assert n!=0,'n is zero!'
return 10/n def main():
foo('') main()

  do_logging.py:

 #python 调试   示例
#logging示例
#2016-8-31 20:31:56
#MengmengCoding
# -*- coding: utf-8 -*- import logging
logging.basicConfig(level=logging.INFO)
s=''
n=int(s)
logging.info('n=%d' %n)
print(10/n)

  do_pdb.py:

 #python 调试   示例
#pdb示例
#2016-8-31 20:44:55
#MengmengCoding
# -*- coding: utf-8 -*- import pdb s=''
n=int(s)
pdb.set_trace() #运行到这里会自动暂停
print(10/n)

  

  

python基础——调试的更多相关文章

  1. python基础===利用PyCharm进行Python远程调试(转)

    原文链接:利用PyCharm进行Python远程调试 背景描述 有时候Python应用的代码在本地开发环境运行十分正常,但是放到线上以后却出现了莫名其妙的异常,经过再三排查以后还是找不到问题原因,于是 ...

  2. python基础之错误、调试(异常处理)

    在程序运行过程中,总会遇到各种各样的错误. 有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修复的. 有的错误是用户输入造成的,比如让用 ...

  3. Python之路【第二篇】:Python基础

    参考链接:老师 BLOG : http://www.cnblogs.com/wupeiqi/articles/4906230.html 入门拾遗 一.作用域 只要变量在内存中就能被调用!但是(函数的栈 ...

  4. python基础——定制类

    python基础——定制类 看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的. __slots__我们已经知道怎么用了,__len__()方 ...

  5. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  6. Python基础教程【读书笔记】 - 2016/7/31

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第十波:第10章  充电时刻 Python语言的核心非常强大,同时还提供了更多值得一试的工具.Python的标准安装包括 ...

  7. 第一篇:python基础

    python基础   python基础 本节内容 python起源 python的发展史 为什么选择python3 第一个python程序 变量定义 表达式和运算符 用户输入 流程控制 判断 流程控制 ...

  8. Day1 - Python基础1 介绍、基本语法、流程控制

    Python之路,Day1 - Python基础1   本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼 ...

  9. Day1 Python基础学习

    一.编程语言分类 1.简介 机器语言:站在计算机的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件 汇编语言:站在计算机的角度,简写的英文标识符取代二进制去编写程序,本质仍然是直接操作 ...

随机推荐

  1. HDU1102(最小生成树Kruskal)

    开学第三周.........真快尼 没有计划的生活真的会误入歧途anytime 表示不开心不开心不开心 每天都觉得自己的生活很忙 又觉得想做的事又没有完成 这学期本来计划重点好好学算法,打码码,臭臭美 ...

  2. iOS开发——UI基础-屏幕适配

    一.适配 1.什么是适配?适应.兼容各种不同的情况 2.移动开发中,适配的常见种类 2.1系统适配 针对不同版本的操作系统进行适配 2.2屏幕适配 针对不同大小的屏幕尺寸进行适配 二.点和像素 1.在 ...

  3. Git秘籍:在 Git 中进行版本回退

    导读 在这篇文章中,你将学到如何查看项目中的历史版本,如何进行版本回退,以及如何创建 Git 分支以便你可以大胆尝试而不会出现问题.快来试试吧. 在你的 Git 项目的历史中,你的位置就像是摇滚专辑中 ...

  4. Pragma如何分组

    Pragma Pragma Mark #pragma mark - 是一个在类内部组织代码并且帮助你分组方法实现的好办法. 我们建议使用 #pragma mark - 来分离: 不同功能组的方法 pr ...

  5. HttpClient session

    session概述 session机制 session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息. 当程序需要为某个客户端的请求创建一个session ...

  6. ionic不同view跳转到同一个

    ionic不同view跳转到同一个 view并保留历史的路由设计 上代码:state 里面新加一个状态 .state("other", { url: "/other&qu ...

  7. [转]Python的ASCII, GB2312, Unicode , UTF-8

    2007-12-13 10:50:47|  分类: Python实用软件编|举报|字号 订阅     ASCII 是一种字符集,包括大小写的英文字母.数字.控制字符等,它用一个字节表示,范围是 0-1 ...

  8. phpcms分页用法简介

    PHPCMS分页的用法 前面需要有引用的list,代码如下: {pc:content action="lists" catid="11" order=" ...

  9. git cherry-pick简介

    本文编辑整理自: http://sg552.iteye.com/blog/1300713 http://web.mit.edu/bitbucket/git-doc/git-cherry-pick.tx ...

  10. POJ 2121

    http://poj.org/problem?id=2121 一道字符串的转换的题目. 题意:就是把那个英文数字翻译成中文. 思路:首先打表,然后把每一个单独的单词分离出来,在组合相加相乘. #inc ...