几年来我在答疑群、论坛、公众号、知乎回答的各类问题,没有一万也有八千。其中有三分之二以上都是在帮人看报错,帮人 debug(调试代码)。编程
能够说,会不会 debug,有没有 debug 的意识,懂不懂 debug 的技巧,是有没有入门编程的重要标志。然而绝大多数的编程书籍和课程都不会强调这点。教的人和学的人都只关注明面上的知识点,却每每忽略了学习的本质在于“授之以渔”。编辑器
在咱们的码上行动基础课程里,《如何 debug》是必须掌握的一个章节。后来发现很多有基础的同窗直接参与爬虫课程,但一样缺失 debug 的基本功,因而我又把 debug 做为前序章节加入到爬虫课程里。函数
为何不少初学者会以为编程论坛里的人都不大友好?我常常对提问者说:你这个问题我没法回答,由于你缺乏最基本的调试信息。而若是你把调试信息提供到位了,基本也就不须要我回答了。归根结底,是历来没有人告诉过初学者,你得先调试。大部分人都是碰了不少次壁最后终于明白,啊多么痛的领悟!单元测试
今天我就从 debug 课程里挑选最关键的几点讲一下。不要光 mark,如今就看一遍,嫌长就看加粗高亮部分。之后开发中再遇到问题,按照如下要点自查。学习
初学者一半以上的问题是低级错误,好比缩进错误(空格、tab混用)、变量先后命名不一致(拼写错误)、函数调用时传递的参数不对、少引号括号、用了中文全角等等。这些人眼很难一下发现的错误,代码编辑器能够在写代码的时候就给你提示出来。测试
如图中,分别有一个函数名写错了、一个变量名拼错了,还有一个 if 前面的空格我用了 Tab 键而不是 4 个空格。Pycharm 在你写代码时就会给出高亮或者波浪线的提示,把鼠标移上去还能够看到错误的提示。不然这些错误是很难被发现的。网站
另外,IDE 的一个重要功能就是能够自动补全代码,省事并且不容易出错。搜索引擎
Python 自带的 IDLE 在这方面作得并很差,刚起步时能够用用,上手后尽快转。我的推荐用 Pycharm,即便是功能相对较少的免费社区版本,也足够应付开发时需求。VSCode 也是很好的选择。以前有过两篇介绍文章,公众号里回复 pycharm 可查看。编码
绝大多数问题不是直接在代码层面就出现的,而是运行时才发生。这时候正常都会致使程序中断并输出报错信息。通常从报错信息里就能够看出报错的位置和缘由。人工智能
不少初学者怕看报错信息,这不行。即便英语很差,也尝试着去看,套路就那么些,看几回你就大概熟悉了,但对你调试的帮助很是大。
不过有时报错显示的位置是有问题的,这种状况一般的缘由都是前面某一行的括号或者引号有问题,而致使后面的代码错乱。因此若是报错指出的位置看不出问题,试着往前看一看。
在代码中使用 try...except 能够避免程序因异常中断。但在开发时不要使用异常处理,不然阻止了报错信息的发出,影响调试。
报错信息还有个用处就是直接复制到搜索引擎里进行搜索,而这方面 Google 的结果比百度要好,英文网站要比中文网站好。(怎样用 Google 这个话题不便在此公开讨论。)
这一点是最重要的!
在程序中输出并分析 log(日志)是一种很基本但却很灵活颇有效的调试方式。使用 print 就是 log 的最经常使用方法。
log 的做用主要是:
a. 肯定程序的运行路径。一个函数有没有被调用,一个 if 块有没有被执行,一个 while 循环执行了几回,到了哪一步中断了,均可以经过 print 出相关信息来查看。
b. 查看变量的状态。程序自身的报错会告诉你发生了什么错误,但你还须要找出为何会发生错误。经过 print 输出出错语句涉及到的相关变量的值和类型,能够帮助分析出错缘由。
c. 找出出错位置。每每错误的缘由并不在报错的位置,因此多输出一些标记,多 print 不一样位置的变量值,查看变量在运行过程当中值的变化状况,能够观察是在哪里发生了问题。
几个经过 log 调试的经验技巧:
a. 多输出一些辅助信息,方便本身查看,否则一堆数据看花眼。好比我通常输出时会标注上变量名,再输出变量类型,以及变量的值。好比:
b. 在出错行以前输出。报错行涉及的一些变量,他们的数值和类型,全都输出出来,看看和预期是否一致。
c. 一行作一件事。若是你出错的一行里连续调用了多个函数或运算,请分开写,分开输出。
d. 对于字符串,直接 print 会被转义和解码,影响对变量实际值的观察。能够用 print(repr(text)) 或 print([text]) 的方式查看。
e. 对于编码问题,用好 type 方法和 chardet 库辅助判断。这点以前编码相关的文章里有说明,公众号里回复 pycharm 可查看。
f. 为了方便记录和回溯问题日志,一般也会将 log 输出到文件。也有专门的 logging 模块作这事。
记住:print 不要钱,能用多少是多少!确保你清楚程序运行的状态细节。
断点调试看参考以前文章 如何在 Python 中使用断点调试,这里再也不复述。
前面这些基本是操做层面的具体 debug 方法,下面我再来谈点 debug 的思想和原则:
软件开发中有一个“单元测试”的概念:若是你写了一个函数,应该先运行下这个函数是否是正常,各类参数下会不会出现错误。这样能够把问题控制在较小的范围内解决。
好比作爬虫没有抓到正确数据,那么究竟是 (1)请求来的数值不对,仍是 (2)文本处理方法不对?若是你认为是文本处理方法没有问题,就手动给定一个正确格式的字符串文本,应该能够获得正确的结果。这就至关于控制了因素(2),只改变因素(1),根据执行结果就能够确认或排除问题的所在。
二分查找法是一个定位问题的技巧。若是你的代码里有问题,那么问题要么在前半段,要么在后半段。你先把后半段代码去掉执行,看看程序是否还报错,就知道错误在哪部分。依次类推,不断折半,直到找到引起报错的代码。
有的错误不是每次出现。这时候最好别急着去改代码,而是想办法能够稳定重现问题。当你能顺利重现问题的时候,一般离分析解决它也不远了。解决了以后,再按照以前重现的方式验证修改是否确实有效。
不管是开发代码,仍是调试 debug,在作一个动做前要清楚本身的目的是什么,而不是盲目地进行改动。不要猜!我常常会看见一些新手遇到问题以后,反复执行代码,或者不断调整参数,妄想某次执行程序就能神奇地经过了。这是一个很很差的态度,请避免。要恪守逻辑,知道如今要解决的问题是什么,须要获得那些信息,可能的假设是什么,如何经过修改代码去验证你的判断,这样才是合理的 debug 方式。
以上就是一些 debug 的基本思想和技巧。这里仅仅是概要精华,操做起来远不止这么多,同时还须要实际的练习才能掌握。我能作的就是给你的编程技能树下埋一颗种子,能不能生根发芽,就看各位本身的浇灌了。(我相信,即便我这里都说过了,仍是会有不少人依旧犯上述说起的错误 ╮(╯_╰)╭ 随缘吧,师傅领进门,修行在我的……)
想要深刻了解更多编程的思想和技巧,欢迎来咱们的码上行动或知识星球。
下课!
════
其余文章及回答:
如何自学Python | 新手引导 | 精选Python问答 | Python单词表 | 知乎下载器 | 人工智能 | 嘻哈 | 爬虫 | 我用Python | 高考 | requests | AI平台
欢迎搜索及关注:Crossin的编程教室