Python 异常处理及程序调试

时间:2020-8-24 作者:admin


作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

异常概述

在程序运行过程中,经常会遇到各种各样的错误,这些错误统称为 “异常”。这些异常有的是由于开发者一时疏忽将关键字敲错导致的,这类错误多数产生的是 SyntaxError: invalid syntax(无效的语法),这将直接导致程序不能运行。这类异常是显式的,在开发阶段很容易被发现。还有一类是隐式的,通常和使用者的操作有关。

Python 中常见的异常如下表所示

异常 描述
NameError 尝试访问一个没有声明的变量引发的错误
IndexError 索引超出序列范围引发的错误
IndentationError 缩进错误
ValueError 传入的值错误
KeyError 请求一个不存在的字典关键字引发的错误
IOError 输入输出错误(如要读取的文件不存在)
ImportError 当 import 语句无法找到模块或 from 无法在模块中找到相应的名称时引发的错误
AttributeError 尝试访问未知的对象属性引发的错误
TypeError 类型不合适引发的错误
MemoryError 内存不足
ZeroDivisionError 除数为 0 引发的错误

异常处理语句

在程序开发时,有些错误并不是每次运行都会出现的。这时就需要在开发程序时对可以出现异常的情况进行处理。在 Python 中,提供了 try…except 语句捕获并处理异常。在使用时,把可能产生异常的代码放在 try 语句块中,把处理结果放在 except 语句块中,这样,当 try 语句块中的代码出现错误,就会执行 except 语句块中的代码,如果 try 语句块中的代码没有错误,那么 except 语句块将不执行。

示例:

def division():
    '''
    功能:分苹果
    :return: 无
    '''

    print("\n==================== 分苹果了 ====================\n")
    apple = int(input("请输入苹果的个数: "))
    children = int(input("请输入小朋友的个数: "))
    result = apple // children
    remain = apple - result * children
    if remain > 0:
        print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个,剩余", remain, "个")
    else:
        print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个")

if __name__ == '__main__':
    try:
        division()
    except ZeroDivisionError:
        print("\n出错了 ~_~  小朋友的个数不能为 0 !")
    except ValueError as e:
        print("输入错误: ", e)

多次运行示例的结果如下所示:

==================== 分苹果了 ====================

请输入苹果的个数: asda
输入错误:  invalid literal for int() with base 10: 'asda'

==================== 分苹果了 ====================

请输入苹果的个数: 12
请输入小朋友的个数: 0

出错了 ~_~  小朋友的个数不能为 0 !

==================== 分苹果了 ====================

请输入苹果的个数: 12
请输入小朋友的个数: 5
12 个苹果,评价分给 5 个小朋友,每人分 2 个,剩余 2 个

完整的异常处理语句应该包含 else 和 finally 代码块。else 代码块在程序没有抛出异常时执行,而 finally 代码块无论是否出现异常都会被执行

示例:

if __name__ == '__main__':
    try:
        division()
    except ZeroDivisionError:
        print("\n出错了 ~_~  小朋友的个数不能为 0 !")
    except ValueError as e:
        print("输入错误: ", e)
    else:
        print("分苹果顺利完成!")
    finally:
        print("进行了一次分苹果操作!")

如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用 raise 语句在函数或方法中抛出异常。在应用 raise 抛出异常时,要尽量选择合理的异常对象,而不应该抛出一个与实际内容不相关的异常。

示例:

def division():
    '''
    功能:分苹果
    :return: 无
    '''

    print("\n==================== 分苹果了 ====================\n")
    apple = int(input("请输入苹果的个数: "))
    children = int(input("请输入小朋友的个数: "))
    if apple < children:
        raise ValueError("苹果太少了,不够分!")

    result = apple // children
    remain = apple - result * children
    if remain > 0:
        print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个,剩余", remain, "个")
    else:
        print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个")

if __name__ == '__main__':
    try:
        division()
    except ZeroDivisionError:
        print("\n出错了 ~_~  小朋友的个数不能为 0 !")
    except ValueError as e:
        print("输入错误: ", e)
    else:
        print("分苹果顺利完成!")
    finally:
        print("进行了一次分苹果操作!")

上述例子的运行结果为:

==================== 分苹果了 ====================

请输入苹果的个数: 3
请输入小朋友的个数: 4
输入错误:  苹果太少了,不够分!
进行了一次分苹果操作!

程序调试

在程序开发过程中,免不了会出现一些错误,有语法方面的,也有逻辑方面的。语法方面的错误比较容易检测,因为程序会直接停止,并且给出错误提示。逻辑错误就不太容易发现了。因为程序可能会一直执行下去,但结果是错误的。所以作为一名程序员,掌握一定的程序调试方法,可以说是一项必备技能。
在这里插入图片描述
在这里插入图片描述

在程序开发过程中,除了使用系统自带的调试工具进行调试外,还可以在代码中通过 print() 函数把可能出现问题的变量输出进行查看。这种命令会产生很多垃圾信息,所以调试之后还需要将其删除,比较麻烦。除此之外,Python 还提提供了另外的方法 – 使用 assert 语句调试程序。assert 的中文意思是断言,它一般用于对程序某个时刻必须满足的条件进行验证。

示例:

def division():
    '''
    功能:分苹果
    :return: 无
    '''

    print("\n==================== 分苹果了 ====================\n")
    apple = int(input("请输入苹果的个数: "))
    children = int(input("请输入小朋友的个数: "))
    assert apple > children, "苹果不够分!"

    result = apple // children
    remain = apple - result * children
    if remain > 0:
        print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个,剩余", remain, "个")
    else:
        print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个")

if __name__ == '__main__':
    try:
        division()
    except ZeroDivisionError:
        print("\n出错了 ~_~  小朋友的个数不能为 0 !")
    except ValueError as e:
        print("输入错误: ", e)
    else:
        print("分苹果顺利完成!")
    finally:
        print("进行了一次分苹果操作!")

触发断言:

==================== 分苹果了 ====================

请输入苹果的个数: 5
请输入小朋友的个数: 6
进行了一次分苹果操作!
Traceback (most recent call last):
  File "D:/Python/Demo/main.py", line 21, in <module>
    division()
  File "D:/Python/Demo/main.py", line 10, in division
    assert apple > children, "苹果不够分!"
AssertionError: 苹果不够分!

通常情况下,assert 语句可以和异常处理语句结合使用。

try:
    division()
except AssertionError as e:
    print("\n输入有误:", e)

这样再执行程序时就不会直接抛出异常了。

注意:assert 语句只在调式阶段有效,我们可以通过在执行 Python 命令时加入 -O(大写)参数来关闭 assert 语句

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。