>>> from env_helper import info; info()
页面更新时间: 2022-03-23 09:09:04
运行环境:
    Linux发行版本: Debian GNU/Linux 11 (bullseye)
    操作系统内核: Linux-5.10.0-11-amd64-x86_64-with-glibc2.31
    Python版本: 3.9.2

12.1. 调试

这部分会介绍了一些工具和技巧,用于寻找程序中缺陷的来源, 帮助你更快更容易地修复缺陷。

代码中很容易会产生一些缺陷。 程序员之间流传着一个老笑话:“编码占了编程工作量的90%,调试占了另外90%。”

好在,有一些工具和技巧可以确定你的代码在做什么, 以及哪儿出了问题。

首先,你要查看日志和断言。 这两项功能可以帮助你尽早发现缺陷。 一般来说,缺陷发现的越早,就越容易修复。

其次,你要学习如何使用调试器。调试器是 IDLE 的一项功能, 它可以一次执行一条指令,在代码运行时,让你有机会检查变量的值,并追踪程序运行时值的变化。 这个过程是仔细检查代码运行情况的过程,可以帮助查看程序运行时其中实际的值(比如循环中的某个过程), 而不是通过源代码推测值可能是什么。

12.1.1. 抛出异常

当 Python 试图执行无效代码时,就会抛出异常。 可以使用 tryexcept 语句来处理Python 的异常,这样程序就可以从你预期的异常中恢复。 但你也可以在代码中抛出自己的异常。抛出异常相当于是说: “停止运行这个函数中的代码,将程序执行转到 except 语句”。

抛出异常使用 raise 语句。在代码中, raise 语句包含以下部分:

  • raise 关键字;

  • Exception 函数的调用;

  • 传递给 Exception 函数的字符串,包含有用的关于错误的信息。

例如,在交互式环境中输入以下代码:

>>> raise Exception('This is the error message.')
---------------------------------------------------------------------------

Exception                                 Traceback (most recent call last)

<ipython-input-10-4d63d15f2d65> in <module>
----> 1 raise Exception('This is the error message.')


Exception: This is the error message.

如果没有 tryexcept 语句覆盖抛出异常的 raise 语句, 该程序就会崩溃,并显示异常的出错信息。

12.1.2. 捕获异常

使用 tryexcept 语句, 你可以更优雅地处理错误,而不是让整个程序崩溃。

通常是调用该函数的代码知道如何处理异常,而不是该函数本身。 所以你常常会看到 raise 语句在一个函数中, tryexcept 语句在调用该函数的代码中。

例如,以下代码定义函数:

>>> def boxPrint(symbol, width, height):
>>>     if len(symbol) != 1:
>>>         raise Exception('符号必须是单个字符.')
>>>     if width <= 2:
>>>         raise Exception('宽度必须大于2.')
>>>     if height <= 2:
>>>         raise Exception('高必须大于2.')
>>>     print(symbol * width)
>>>     for i in range(height - 2):
>>>         print(symbol + (' ' * (width - 2)) + symbol)
>>>     print(symbol * width)

然后开始运行,查看抛出异常的情景:

>>> for sym, w, h in (('*', 4, 4), ('8', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)):
>>>     print()
>>>     try:
>>>         boxPrint(sym, w, h)
>>>     except Exception as err:
>>>         print('异常出现: ' + str(err))
****
*  *
*  *
****

88888888888888888888
8                  8
8                  8
8                  8
88888888888888888888

异常出现: 宽度必须大于2.

异常出现: 符号必须是单个字符.

这里我们定义了一个 boxPrint() 函数,它接受一个字符、 一个宽度和一个高度。它按照指定的宽度和高度, 用该字符创建了一个小盒子的图像。这个盒子被打印到屏幕上。

假定我们希望该字符是一个字符,宽度和高度要大于2。我们添加了 if 语句,如果这些条件没有满足,就抛出异常。稍后, 当我们用不同的参数调用 boxPrint()时, try/except 语句就会处理无效的参数。

这个程序使用了 except 语句的 except Exception as err 形式。 如果 boxPrint() 返回一个 Exception 对象, 这条语句就会将它保存在名为err的变量中。 Exception对象可以传递给 str() , 将它转换为一个字符串,得到用户友好的出错信息。