资讯专栏INFORMATION COLUMN

开发5分钟,调试2小时 - 该如何debug?

Charles / 631人阅读

摘要:但在开发时不要使用异常处理,否则阻止了报错信息的发出,影响调试。的作用主要是确定程序的运行路径。二分查找法是一个定位问题的技巧。

前言

几年来我在答疑群、论坛、公众号、知乎回答的各种问题,没有一万也有八千。其中有三分之二以上都是在帮人看报错,帮人 debug(调试代码)

可以说, 会不会 debug,有没有 debug 的意识,懂不懂 debug 的技巧,是有没有入门编程的重要标志 。然而绝大多数的编程书籍和课程都不会强调这点。教的人和学的人都只关注明面上的知识点,却往往忽略了学习的本质在于“授之以渔”。

在我们的 码上行动基础课程 里,《 如何 debug 》是必须掌握的一个章节。后来发现不少有基础的同学直接参与 爬虫课程 ,但同样缺失 debug 的基本功,于是我又把 debug 作为前序章节加入到爬虫课程里。

为什么很多初学者会觉得编程论坛里的人都不大友好?我经常对提问者说:你这个问题我无法回答,因为你 缺少最基本的调试信息 。而如果你把调试信息提供到位了,基本也就不需要我回答了。归根结底,是从来没有人告诉过初学者, 你得先调试 。大部分人都是碰了很多次壁最后终于明白,啊多么痛的领悟!

今天我就从 debug 课程里挑选最关键的几点讲一下。不要光 mark,现在就看一遍, 嫌长就看加粗高亮部分 。以后开发中再遇到问题,按照以下要点自查。

debug 自查方法 1. 选一个好的 IDE

初学者一半以上的问题是 低级错误 ,比如 缩进错误(空格、tab混用)、变量前后命名不一致(拼写错误)、函数调用时传递的参数不对、少引号括号、用了中文全角 等等。这些人眼很难一下发现的错误,代码编辑器可以在写代码的时候就给你提示出来。

如图中,分别有一个函数名写错了、一个变量名拼错了,还有一个 if 前面的空格我用了 Tab 键而不是 4 个空格。Pycharm 在你写代码时就会给出高亮或者波浪线的提示,把鼠标移上去还可以看到错误的提示。否则这些错误是很难被发现的。

另外,IDE 的一个重要功能就是可以 自动补全代码 ,省事而且不容易出错。

Python 自带的 IDLE 在这方面做得并不好,刚起步时可以用用,上手后尽快转。 个人推荐用 Pycharm ,即使是功能相对较少的 免费社区版本 ,也足够应付开发时需求。 VSCode 也是很好的选择之前有过两篇介绍文章, 公众号里回复 pycharm 可查看

2. 学会看报错信息

绝大多数问题不是直接在代码层面就出现的,而是 运行时才发生 。这时候正常都会导致 程序中断并输出报错信息 。一般从报错信息里就可以看出 报错的位置和原因

很多初学者怕看报错信息,这不行。即使英语不好,也尝试着去看,套路就那么些,看几次你就大概熟悉了,但对你调试的帮助非常大。

不过有时报错显示的位置是有问题的,这种情况通常的原因都是前面某一行的括号或者引号有问题,而导致后面的代码错乱。所以 如果报错指出的位置看不出问题,试着往前看一看

在代码中使用 try...except 可以避免程序因异常中断。但在 开发时不要使用异常处理 ,否则阻止了报错信息的发出,影响调试。

报错信息还有个用处就是 直接复制到搜索引擎里进行搜索 ,而这方面 Google 的结果比百度要好,英文网站要比中文网站好。(怎样用 Google 这个话题不便在此公开讨论。)

3. 别舍不得用 print

这一点是最重要的!

在程序中输出并分析 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 不要钱,能用多少是多少! 确保你清楚程序运行的状态细节。

4. 断点调试

断点调试看参考之前文章 如何在 Python 中使用断点调试,这里不再复述。

debug 的思想和原则

前面这些基本是操作层面的具体 debug 方法,下面我再来谈点 debug 的思想和原则

1. 缩小出错的范围

软件开发中有一个“单元测试”的概念:如果你写了一个函数,应该先运行下这个函数是不是正常,各种参数下会不会出现错误。这样可以 把问题控制在较小的范围内 解决。

2. 控制变量法 + 二分查找法

比如做爬虫没有抓到正确数据,那么到底是 (1)请求来的数值不对,还是 (2)文本处理方法不对?如果你认为是文本处理方法没有问题,就手动给定一个正确格式的字符串文本,应该可以得到正确的结果。这就相当于 控制了因素(2),只改变因素(1),根据执行结果就可以确认或排除问题的所在

二分查找法是一个定位问题的技巧。如果你的代码里有问题,那么问题要么在前半段,要么在后半段。你先把后半段代码去掉执行,看看程序是否还报错,就知道错误在哪部分。依次类推, 不断折半,直到找到引发报错的代码

3. 先重现,再解决,最后验证

有的错误不是每次出现。这时候最好别急着去改代码,而是 想办法可以稳定重现问题 。当你能顺利重现问题的时候,通常离分析解决它也不远了。解决了之后, 再按照之前重现的方式验证修改 是否确实有效。

4. 想清楚再动手

不论是开发代码,还是调试 debug,在做一个动作前要清楚自己的目的是什么,而不是盲目地进行改动。 不要猜! 我经常会看见一些新手遇到问题之后,反复执行代码,或者不断调整参数,妄想某次执行程序就能神奇地通过了。这是一个很不好的态度,请避免。 要恪守逻辑 ,知道现在要解决的问题是什么,需要得到那些信息,可能的假设是什么,如何通过修改代码去验证你的判断,这样才是合理的 debug 方式。

以上就是一些 debug 的基本思想和技巧。这里仅仅是概要精华,操作起来远不止这么多,同时还需要实际的练习才能掌握。我能做的就是给你的编程技能树下埋一颗种子,能不能生根发芽,就看各位自己的浇灌了。(我相信,即使我这里都说过了,还是会有很多人依旧犯上述提及的错误 ╮(╯_╰)╭ 随缘吧,师傅领进门,修行在个人……)

想要深入了解更多编程的思想和技巧,欢迎来我们的 码上行动知识星球

下课!

════

其他文章及回答:

如何自学Python | 新手引导 | 精选Python问答 | Python单词表 | 知乎下载器 | 人工智能 | 嘻哈 | 爬虫 | 我用Python | 高考 | requests | AI平台

欢迎搜索及关注: Crossin的编程教室

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42509.html

相关文章

  • 我们一直谈论“写代码”,但你会“读代码”吗?

    摘要:只有能看懂代码,你才能快速准确地定位代码中的问题。要写出很的代码,少不了阅读优秀的源码。我们的论坛和答疑群里,有一些同学会查看并解答其他人的代码问题。实际上,我觉得就是没看懂你只是看懂了每一行代码的意思,但并没有理解整个代码的设计。 编程,又被称作 写代码 。这个说法有可能会带来一点点误解,让人觉得如何写是学习编程要解决的主要问题。但事实并非如此。尽管最终代码要在键盘上敲出来,但这个过...

    2i18ns 评论0 收藏0
  • 编程新手如何更好地提问

    摘要:如果你也曾遭遇这样的问题,或今后打算在编程社区里成长,请务必看看我接下来要说的东西如何正确地在编程社区提问绝大部分得不到满意回答甚至引来不满的问题,都是问题本身的原因。对新手来说,的可能性更大。 学编程难免遇到问题,遇到问题难免要上网求助。然而有过不少同学向我诉苦,说 在网上提问没有人回答,有的还收到一些不是很友好的回复 。我自己也在经常上的论坛上目睹过类似的帖子。以至于有人说,程序员...

    Salamander 评论0 收藏0
  • 我是如何在自学编程9个月后找到工作的

    摘要:昨天在我在国外网站上看到一篇文章,作者分享了他自学编程个月后找到工作的经历。而本文中,我主要针对想要通过学习编程找工作的角度来谈。我在年月犯了一个错误我认为首要任务是找到一份前端开发的工作。 昨天在我在国外网站 reddit 上看到一篇文章,作者分享了他 自学编程 9 个月后找到工作 的经历。文章不到一天就得到3千多赞,2百条回复。我看了下内容,非常中肯,其中有不少建议也是我在编程教室...

    gaosboy 评论0 收藏0
  • Nginx location 配置踩坑过程分享

    摘要:所以到目前为止,基本可以肯定是的上出了一些问题。问题解决因篇幅有限,为了直面本次问题的核心,我不再贴出完整的配置,我简化此次问题的模型。 这是五个小时与一个字符的战斗 是的,作为一个程序员,你往往发现,有的时候你花费了数小时,数天,甚至数星期来查找问题,但最终可能只花费了数秒,改动了数行,甚至几个字符就解决了问题。这次给大家分享一个困扰了我很久,我花了五个小时才查找出问题原因...

    alighters 评论0 收藏0
  • 本地测试没问题,机器人测试错误的简单规避办法

    摘要:曲线救国既然只有机器人报错,那么本地测试好后,可以考虑将机器人报错的部分做排除。虽然好用,但却不能自己定义具体的信息它的就那几种,比如就一个打造自己的单元测试服务器迫在眉睫。接收到信息后,检出相应的分支,执行单元测试,并将测试的结果推送给 本地环境可以跑通,但只要一上机器人环境,便会出现错误。一般这种情况都是由于本地与travis的JDK版本不一致造成的。然而,机器人又有日志大粘限制,...

    stefan 评论0 收藏0

发表评论

0条评论

Charles

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<