如何调试自己写的实用脚本?

wen 实用脚本 1

本文目录导读:

如何调试自己写的实用脚本?

  1. 核心原则:像侦探一样思考
  2. 预防性调试:在写代码时就埋好“雷达”
  3. 基础调试法:print 语句的进阶用法
  4. 交互式调试器(超级推荐!)
  5. 利用 IDE(集成开发环境)进行可视化调试
  6. 针对特定场景的“急救包”
  7. 调试流程建议

调试自己写的实用脚本是开发者生涯中非常重要的一项技能,好的调试方法能帮你节省大量时间,还能避免一些难以发现的错误。

下面我为你整理了一套从简单到复杂、从通用到具体的调试策略,适用于常见的脚本语言(如 Python、Bash、JavaScript 等)。

核心原则:像侦探一样思考

  1. 复现:找到稳定触发 bug 的方法。
  2. 定位:从“脚本出了问题”缩小到“第 4 行出了问题”。
  3. 隔离:确认是输入数据、逻辑错误还是依赖问题。
  4. 修复:修改代码并验证。

下面是一些非常实用的调试技巧,按推荐程度排序:


预防性调试:在写代码时就埋好“雷达”

这是最高效的调试,目的不是找 bug,而是不让 bug 出现。

  1. 优秀的日志(Logging):不要只用 print,使用专业的日志库。

    • Pythonimport logging

      import logging
      logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
      def process_data(data):
          logging.debug(f"输入数据: {data}")
          # ... 做一些操作 ...
          result = data['key'] # key 不存在会报错
          logging.info(f"处理结果: {result}")
          return result
    • 好处:可以按级别(DEBUG, INFO, WARNING, ERROR)过滤日志,写到文件里,对生产环境非常友好。

  2. 使用断言(Assert)

    • 在代码里显式声明“这个值此时不应该为 None”。
      def calculate_average(grades):
          assert len(grades) > 0, "成绩列表不能为空!"
          return sum(grades) / len(grades)
    • 注意:断言在 Python 生产环境(-O 优化模式)下可能被关闭,所以只用于开发调试。

基础调试法:print 语句的进阶用法

如果你的脚本很简单,或者没有安装复杂的工具,print 仍然是利器,但要用得有技巧。

  1. 标签化打印:不要只打印变量,要打印它“是谁”。

    • print(data)
    • print(f"[DEBUG] 进入函数process_data,输入数据data的值为: {data[:10]}")
  2. 打印关键中间状态:在循环、条件判断、函数调用前后打印。

    for i, item in enumerate(list_of_items):
        print(f"迭代次数: {i}, 当前项: {item}")
        # 检查某个条件
        if item < 0:
            print(f"[WARNING] 在第 {i} 处发现负数: {item}")
  3. 使用 repr() 而非 str():当你打印字符串时,repr() 能显示转义字符和特殊格式,避免被迷惑。

    s = "hello\nworld"
    print(s)   # 输出两行,可能看不出换行符
    print(repr(s))  # 输出 'hello\nworld'

交互式调试器(超级推荐!)

这是最专业的调试方式,适用于复杂逻辑,它让你能暂停代码,一行一行执行,并检查所有变量的值

Python:pdbipdb (推荐 ipdb)

  1. 安装pip install ipdb

  2. 使用:在代码中你想暂停的地方插入断点。

    import ipdb
    def complex_function(x, y):
        result = x + y
        ipdb.set_trace()  # <--- 程序会停在这里,进入交互模式
        result = result * x
        return result
  3. 常用命令(在交互界面输入)

    • n (next):执行下一行。
    • s (step):进入函数内部。
    • c (continue):继续执行直到下一个断点。
    • p variable_name:打印变量的值。
    • l (list):显示当前行附近的源代码。
    • q (quit):退出调试器。

更现代的选择:pdb++ptvsd 但对于大多数脚本,ipdb 已经足够强大。

Node.js/JavaScript:使用 node inspect

# 在代码中插入
debugger;
# 然后运行脚本
node inspect your_script.js

Bash:bash -xset -x

Bash 脚本的调试比较痛苦,但也很有效。

  • 全局调试:运行脚本时加上 -x 参数,会打印出每一条执行的命令和参数。
    bash -x your_script.sh arg1 arg2
  • 局部调试:在脚本里插入 set -xset +x
    echo "这是一段没有调试的信息"
    set -x  # 开启调试
    for i in 1 2 3; do
        echo "当前 i 的值是 $i"
    done
    set +x  # 关闭调试
    echo "调试结束"

利用 IDE(集成开发环境)进行可视化调试

如果你使用 VS Code,PyCharm,WebStorm 等现代 IDE,它们的图形化调试器是最直观、最强大的方式。

  • 设置断点:在代码行号左侧点击一下(出现红点)。
  • 点击“调试”按钮:不要点“运行”。
  • 调试控制面板
    • 变量面板:实时查看所有变量的值,会自动更新。
    • 监视(Watch):可以输入表达式,len(name_list) 来动态查看它的长度。
    • 调用栈:看函数是怎么一步步被调用的。
    • 逐过程/逐语句:控制执行流程。

提示:如果你还在用记事本或纯文本编辑器写脚本,强烈建议换成支持调试功能的 IDE,学习成本极低,效率提升巨大。

针对特定场景的“急救包”

如果遇到一些棘手的、难以重现的 bug:

  1. 单元测试(Unit Testing):为你的函数写小测试,这不是调试 bug,而是防止新 bug 引入

    # test_my_function.py
    import my_module
    def test_calculate_total():
        assert my_module.calculate_total([1, 2, 3]) == 6
  2. 异常回溯(Traceback)

    • Pythonimport traceback; traceback.print_exc() 会打印完整的错误调用链。
    • 通用:在 main 函数外层包裹 try...except 捕获所有异常,并打印回溯信息,避免脚本直接退出。
  3. 二分搜索法:如果代码很长,而且不知道哪部分出错了,可以注释掉一半代码,bug 消失了,说明 bug 在被注释的那一半里;然后再注释那一半的一半... 这能快速缩小范围。

调试流程建议

  1. 遇到 bug 时:先冷静,复现它。
  2. 使用断言或日志:快速验证你的假设(这里的数据应该是列表”)。
  3. 插入一个断点(用 IDE 或 ipdb),停在怀疑出错的前面几行。
  4. 单步执行,观察变量变化,看是哪个逻辑分支走错了。
  5. 修复问题后,记得写一个测试或断言,确保这个 bug 不会再回来。

通过有意识地练习这些方法,你的调试速度会越来越快,写出的脚本也会更健壮。

抱歉,评论功能暂时关闭!