【100天精通python】Day18:python程序异常与调试_常用程序调试方式与技巧,如何将调试代码与正式代码分开

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【100天精通python】Day18:python程序异常与调试_常用程序调试方式与技巧,如何将调试代码与正式代码分开

专栏导读

a50b69cc81bb4be29749f2dca96b2f56.png

专栏订阅地址:https://blog.csdn.net/qq_35831906/category_12375510.html

f8d8821388dc41358195b24b9133d6b0.png

一 程序调试

       在Python中,调试是指识别和修复程序中的错误和问题。 调试是程序开发过程中必不可少的一部分,合理利用调试工具和技术可以提高程序开发的效率和质量。Python提供了几种用于调试的工具和技术,帮助开发者找出程序中的bug并进行修复。以下是一些常用的Python程序调试技术:

1 使用print语句

       简单粗暴地在代码中插入print语句,输出变量的值或程序执行的状态,以便跟踪程序的执行过程,查看程序执行过程中的变量状态。

def add_numbers(a, b):
    print("a:", a)
    print("b:", b)
    result = a + b
    print("result:", result)
    return result
add_numbers(2, 3)

2 使用IDE的调试功能

       许多集成开发环境(IDE)都提供了强大的调试功能,可以逐行执行代码,查看变量的值,检查栈跟踪等。常用的Python IDE,如PyCharm、Visual Studio Code、Spyder等都支持调试功能。

2.1 python自带的IDLE调试

(1)打开IDLE, 选择菜单栏的Debug—>Debugger,

eecc9b6b80de4513872b5d77df76002e.png

(2)调出Debug Contorl 对话框,同时python shell窗口显示[DEBUG ON],表示已经处于调试状态

5d577d5b120d4be2ab09762d426c53b1.png

(3)然后再python shell 窗口中选择file,打开要调试的文件,如tickets.py

5309dd6716ae45a5843f70c9501f595b.png

(4)在这个文件上添加需要的断点

设置断点后,程序执行到断点时会暂时终端执行,也可以随时操作继续。

添加断点的方法:在需要添加断点的所在行上,单击鼠标右键,在弹出的快捷菜单中选择SetBreakPoint,

f264179895a9437a814b81b3859dd4af.png

设置断点后,所在行会变成黄色

7f6e0c9a695648ecabb99e0c4778319e.png

(5) tickets.py 中点击Run,IDLE会输出交互,利用DebugControl 的Go 选项进行断点调试。

621d2717eb274b239f80104f440969f8.png

(6)DebugControl中的各项解释如下:

ccd1bf84396a465aac11c4552e85f599.png

2.2 使用pycharm的调试功能

2.2.1 添加断点

鼠标选中需要设置断点的行,点击代码区左边竖栏,可以下断点,再次点击可以取消断点。如下图红色圆圈表示断点设置成功 。

5594acfed5d942e6a36382f02406ca5a.png

2.2.2 运行调试模式

选择右上角的debug按钮或者alt+shift+F9,程序执行时会在下断点的位置停下来。

74d3109cea1c4f119f0460c06d700255.png

进入debug模式之后会出现如图下框。

c9a5d653351f4df59664c7d6ca6c00b5.png

 上图红框的箭头的含义:

d392aa8d1371183dac12483999e4cafb.png

1.show execution point:显示当前所有断点。

2.step over:执行当前的函数或者语句,不会进入当前函数的具体方法,执行完当前的语句之后直接跳到下一句。(例:函数A内存在子函数a时,不会进入子函数a内执行单步调试,而是把子函数a当作一个整体,一步执行。)

3.step into:如果某行调用其他模块的函数,可以进入函数内部,会跳到调用函数的地方执行。(例:函数A内存在子函数a时,会进入子函数a内执行单步调试。)

4.step into my code:与step into是类似的,这个调试的话会进入调试的地方会更细有的时候会进入python本身的库函数执行的地方。

5.step out:返回到上一次的调试的位置。

6.run to cursor:直接跳到下一个断点(从现在的断点跳到打的下一个断点处)。

————————————————

原文链接:https://blog.csdn.net/cunrran/article/details/126975770

3 使用断点调试器pdb

       Python提供了pdb模块,是Python调试器的标准库。可以通过在代码中插入import pdb; pdb.set_trace()语句,在该位置设置一个断点,然后在运行程序时会暂停在断点处,允许你逐行查看代码并检查变量的值。 pdb模块,它是一个交互式调试器,可以在代码中插入调试器命令来检查程序状态。

import pdb
def divide_numbers(a, b):
    pdb.set_trace()  # 插入调试器命令
    return a / b
result = divide_numbers(10, 0)
print("result:", result)

4 使用日志logging模块

       通过在程序中添加日志记录,可以跟踪程序的执行过程并查看各个阶段的输出和变量值。logging模块是Python的内置模块,用于记录程序运行时的日志信息,可以帮助你更好地理解程序的执行流程。

import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug("Debug message")
logging.info("Info message")
logging.warning("Warning message")
logging.error("Error message")

5 使用assert语句

       assert语句用于检查代码中的条件是否满足,如果条件不满足,则抛出AssertionError异常。在程序中添加assert语句,可以在运行时检查程序的状态,如果断言失败,则会触发异常,帮助你快速发现问题所在。

def divide_numbers(a, b):
    assert b != 0, "除数不能为0"
    return a / b
result = divide_numbers(10, 0)
print("result:", result)

6 使用异常追踪

       当程序出现异常时,Python会自动输出异常信息,包括异常类型、发生异常的位置和栈跟踪信息。通过查看异常信息,可以定位和修复错误。

要使用异常追踪进行调试,可以遵循以下步骤:

确定异常类型:当程序运行时发生异常,Python会告诉我们异常的类型,例如ZeroDivisionError、TypeError、ValueError等。首先要根据异常类型来定位问题的大致范围。

查看异常追踪信息:当异常发生时,Python会打印出异常追踪信息,其中包含了异常的类型、文件名、行号等信息。我们可以查看这些信息来了解异常发生的位置。

进行调试:根据异常追踪信息,我们可以找到导致异常的具体代码行。在该位置附近检查代码,查看变量的值,确保代码逻辑正确。可以使用print语句输出变量的值,或者使用Python的内置调试模块pdb进行交互式调试。

以下是一个示例,演示了使用异常追踪进行调试的过程:

def divide_numbers(a, b):
    try:
        result = a / b
        return result
    except ZeroDivisionError as e:
        # 打印异常信息
        print(f"Error: {e}")
        # 打印异常追踪信息
        import traceback
        traceback.print_exc()
def main():
    num1 = 10
    num2 = 0
    # 调用函数,可能会发生ZeroDivisionError异常
    result = divide_numbers(num1, num2)
    print(f"Result: {result}")
if __name__ == "__main__":
    main()

       在上面的示例中,函数divide_numbers用于计算两个数的商,当除数为0时会发生ZeroDivisionError异常。在main函数中调用divide_numbers函数,并捕获异常。

       如果异常发生,我们打印异常信息和异常追踪信息。通过观察异常追踪信息,我们可以知道异常发生的位置在divide_numbers函数的第三行,帮助我们快速定位问题所在。

       使用异常追踪进行调试可以帮助我们快速定位代码中的问题,并修复错误,提高代码的稳定性和可靠性。

7 使用代码分析工具

       Python中有一些代码分析工具,如pylint和pyflakes,可以帮助你找出代码中的错误和潜在问题。

7.1 Pylint

       Pylint是一个强大的静态代码分析工具,可以检查Python代码的语法错误、风格问题和潜在的bug。它会对代码进行严格检查,并生成详细的报告。

       示例:在终端bash运行以下命令,对指定的Python文件进行静态代码分析。

pylint your_file.py

7.2 Pyflakes

       Pyflakes是另一个轻量级的静态代码分析工具,用于查找Python代码中的错误和问题。它主要关注于语法错误和未使用的变量。

       示例:在终端运行以下命令,对指定的Python文件进行代码检查。

pyflakes your_file.py

7.3 Flake8

       Flake8是一个集成了Pylint、Pyflakes和PEP8检查的代码分析工具,它可以同时检查代码的语法、风格和错误。

       示例:在终端运行以下命令,对指定的Python文件进行代码检查。

flake8 your_file.py

7.4 Bandit

       Bandit是一个专门用于检查Python代码中安全问题的工具,它可以帮助你找出潜在的安全漏洞和风险。

       示例:在终端运行以下命令,对指定的Python文件进行安全性分析

bandit your_file.py

使用这些代码分析工具,我们可以快速发现代码中的问题,并及时进行修复,从而提高代码的质量和可维护性。建议在开发过程中定期运行代码分析工具,以确保代码的健壮性和安全性。

二  如何将调试代码与正式代码分开

       在编写正式代码时,通常应该避免在其中包含调试代码和调试语句,以确保代码的可读性和可维护性。调试代码和调试语句主要用于在开发阶段帮助我们调试程序,定位问题和查找错误。在正式代码中保留这些调试代码可能会影响代码的性能和稳定性,而且不利于代码的维护。

       因此建议 在调试过程中,建议将调试代码和调试语句与正式代码分开,以避免在生产环境中产生不必要的输出或影响程序性能。调试完毕后,记得及时清理调试代码和语句。

为了将调试代码和调试语句与正式代码分开,可以考虑以下方法:

(1)使用条件判断

       在编写调试代码时,使用条件判断语句来控制代码的执行。例如,可以使用if语句来判断是否处于调试模式,只有在调试模式下才执行调试代码。

DEBUG_MODE = True
if DEBUG_MODE:
    # 调试代码
    print("Debugging...")
# 正式代码
# ...

(2)使用日志记录

       在调试代码中,可以使用日志记录来输出调试信息,而不是直接在控制台打印调试信息。这样可以方便地开启或关闭调试信息的输出。

import logging
logging.basicConfig(level=logging.DEBUG)
# 调试代码
logging.debug("Debugging...")
# 正式代码
# ...

(3)使用断言

       在调试代码中,可以使用断言来进行条件检查,如果断言失败,则会抛出AssertionError异常。这可以帮助我们在调试时快速定位问题。

DEBUG_MODE = True
if DEBUG_MODE:
    # 调试代码
    assert some_condition, "Some condition failed."
# 正式代码
# ...

通过以上方法,我们可以有效地将调试代码和调试语句与正式代码分开,从而确保在正式环境中不会执行调试代码,提高代码的可靠性和性能。同时,在需要调试时,只需要简单地调整相关的调试标志或参数即可开启调试模式。

上一篇: 100天精通python】Day17:python程序异常与调试_常见异常类型与解决,异常处理语句_LeapMay的博客-CSDN博客


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4天前
|
数据库 Python
[oeasy]python066_如何捕获多个异常_try_否则_else_exception
本文介绍了Python中`try...except...else`结构的使用方法。主要内容包括: 1. **回顾上次内容**:简要复习了`try`和`except`的基本用法,强调了异常处理的重要性。 2. **详细解释**: - `try`块用于尝试执行代码,一旦发现错误会立即终止并跳转到`except`块。 - `except`块用于捕获特定类型的异常,并进行相应的处理。 - `else`块在没有异常时执行,是可选的。 3. **示例代码**:通过具体例子展示了如何捕获不同类型的异常(如`ValueError`和`ZeroDivisionError`),并解释了异常处理
34 24
|
7天前
|
人工智能 Shell 开发工具
[oeasy]python065python报错怎么办_try_试着来_except_发现异常
本文介绍了Python中处理异常的基本方法,重点讲解了`try`和`except`的用法。通过一个计算苹果重量的小程序示例,展示了如何捕获用户输入错误并进行处理。主要内容包括: 1. **回顾上次内容**:简要回顾了Shell环境、Python3游乐场和Vim编辑器的使用。 2. **编写程序**:编写了一个简单的程序来计算苹果的总重量,但发现由于输入类型问题导致结果错误。 3. **调试与修正**:通过调试发现输入函数返回的是字符串类型,需要将其转换为整数类型才能正确计算。
48 32
|
23天前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
58 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
1月前
|
存储 NoSQL 数据库连接
在Python程序中实现LevelDB的海量key的分批次扫描
通过本文的步骤,您可以在Python程序中实现对LevelDB海量key的分批次扫描。这样不仅能够有效地管理大规模数据,还可以避免一次性加载过多数据到内存中,提高程序的性能和稳定性。希望这篇指南能为您的开发工作提供实用的帮助。
74 28
|
2月前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
78 33
|
2月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
52 10
|
2月前
|
Shell 开发工具 Python
如何在vim里直接运行python程序
如何在vim里直接运行python程序
|
2月前
|
安全 API C语言
Python程序的安全逆向(关于我的OPENAI的APIkey是如何被盗的)
本文介绍了如何使用C语言编写一个简单的文件加解密程序,并讨论了如何为编译后的软件添加图标。此外,文章还探讨了Python的.pyc、.pyd等文件的原理,以及如何生成和使用.pyd文件来增强代码的安全性。通过视频和教程,作者详细讲解了生成.pyd文件的过程,并分享了逆向分析.pyd文件的方法。最后,文章提到可以通过定制Python解释器来进一步保护源代码。
87 6
|
2月前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
105 8
|
2月前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!

热门文章

最新文章

推荐镜像

更多