栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python基础篇(十)-- 异常处理

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python基础篇(十)-- 异常处理

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

        异常处理在任何一门编程语言里都是值得关注的一个话题,良好的异常处理可以让你的程序更加健壮,清晰的错误信息更能帮助你快速修复问题。在Python中,和不部分高级语言一样,使用了try/except/else/finally语句块来处理异常。

        Python有两种错误很容易辨认:语法错误和异常。Python的语法错误或者称之为解析错,就是解析代码时出现的错误。当代码不符合Python语法规则时,Python解释器在解析时就会报出SyntaxError语法错误,与此同时还会明确指出最早探测到错误的语句。如少了冒号,或者混用中英文符号的等等。即便 Python程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。大多数的异常都不会被程序处理,都以错误信息的形式展现。例如除数为 0、年龄为负数、数组下标越界等。下图列出常见异常:


图1 Python中常见异常
1 异常处理

        当一个程序发生异常时,代表该程序在执行时出现了非正常的情况,无法再执行下去。默认情况下,程序是要终止的。如果要避免程序退出,可以使用捕获异常的方式获取这个异常的名称,再通过其他的逻辑代码让程序继续运行,这种根据异常做出的逻辑处理叫作异常处理

        开发者可以使用异常处理全面地控制自己的程序。异常处理不仅仅能够管理正常的流程运行,还能够在程序出错时对程序进行必的处理。大大提高了程序的健壮性和人机交互的友好性。

1.1 try/except

        异常捕捉通常使用try/except语句,其基本语法结构如下图所示:

# Mutiple exception in one line
try:
    print(a / b)
except (ZeroDivisionError, TypeError) as e:
    print(e)

        try块有且仅有一个,但except代码块可以有多个,且每个except块都可以同时处理多种异常。当程序发生不同的意外情况时,会对应特定的异常类型,Python解释器会根据该异常类型选择对应的except块来处理该异常。

        try语句的执行流程如下;

  • 首先,执行try子句(在关键字try和关键字except之间的语句)。
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略,系统会自动生成一个异常类型,并将该异常提交给 Python 解释器,此过程称为捕获异常。如果异常的类型和except之后的名称相符,那么对应的except子句将被执行,这个过程被称为处理异常。
  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中,且程序运行终止,Python 解释器也将退出。

        温馨提示: 不管程序代码块是否处于try块中,甚至包括 except块中的代码,只要执行该代码块时出现了异常,系统都会自动生成对应类型的异常。但是,如果此段程序没有用 try包裹,又或者没有为该异常配置处理它的except块,则Python解释器将无法处理,程序就会停止运行;反之,如果程序发生的异常经try捕获并由except处理完成,则程序可以继续执行。

1.2 try/except…else

        在原本的try except结构的基础上,Python异常处理机制还提供了一个else块,也就是原有try except语句的基础上再添加一个else块,即try except else结构。如果使用else块,那么必须放在所有的except子句之后。

        使用else包裹的代码,只有当try块没有捕获到任何异常时,才会得到执行;反之,如果try块捕获到异常,即便调用对应的except处理完异常,else块中的代码也不会得到执行。

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

        使用else子句比把所有的语句都放在try子句里面要好,这样可以避免一些意想不到,而except又无法捕获的异常。

1.3 try-finally

        Python异常处理机制还提供了一个finally语句,通常用来为try块中的程序做扫尾清理工作。

        注意,和else语句不同,finally只要求和try搭配使用,而至于该结构中是否包含except以及else,对于 finally不是必须的(else必须和try except搭配使用)。

        在整个异常处理机制中,finally语句的功能是:无论try块是否发生异常,最终都要进入finally语句,并执行其中的代码块。

        基于finally语句的这种特性,在某些情况下,当try块中的程序打开了一些物理资源(文件、数据库连接等)时,由于这些资源必须手动回收,而回收工作通常就放在finally块中。
Python垃圾回收机制,只能帮我们回收变量、类对象占用的内存,而无法自动完成类似关闭文件、数据库连接等这些的工作。

def main():
    f = None
    try:
        f = open('myfile.txt', 'r', encoding='utf-8')
        print(f.read())
    except FileNotFoundError:
        print('无法打开指定的文件!')
    except LookupError:
        print('指定了未知的编码!')
    except UnicodeDecodeError:
        print('读取文件时解码错误!')
    except Exception as e:
        print('Unexpected Error: {}'.format(e))
    finally:
        if f:
            f.close()
main()
1.4 抛出异常

        如果你需要自主抛出异常一个异常,可以使用raise关键字,等同于C#和Java中的throw,有如下三种常用的用法:

  • raise:单独一个raise。该语句引发当前上下文中捕获的异常(比如在except块中),或默认引发RuntimeError异常。
  • raise异常类名称:raise后带一个异常类名称,表示引发执行类型的异常。
  • raise异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
try:
    a = input("输入一个数:")
    if(not a.isdigit()):
        raise ValueError("a 必须是数字")
except ValueError as e:
    print("引发异常:",repr(e))
    raise
1.5 自定义异常

        Python中自定义自己的异常类型非常简单,只需要要从Exception类继承即可(直接或间接):

class SomeCustomException(Exception):
    pass

class AnotherException(SomeCustomException):
    pass

        一般你在自定义异常类型时,需要考虑的问题应该是这个异常所应用的场景。如果内置异常已经包括了你需要的异常,建议考虑使用内置的异常类型。比如你希望在函数参数错误时抛出一个异常,你可能并不需要定义一个InvalidArgumentError,使用内置的ValueError即可。

补充:

        在实际调试程序的过程中,有时只获得异常的类型是远远不够的,还需要借助更详细的异常信息才能解决问题。

        捕获异常时,有 2 种方式可获得更多的异常信息,分别是:

  • 使用sys模块中的exc_info方法;
  • 使用traceback模块中的相关函数。

        了解更多请参考,Python sys.exc_info()方法:获取异常信息和traceback模块:获取异常信息

        Python assert(断言)用于判断一个表达式,在表达式条件为false的时候触发异常。

        断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况。

assert 1 == 2   # 判断条件为False,抛出异常

参考
  • Python中的异常处理:https://segmentfault.com/a/1190000007736783
  • Python异常处理机制:http://c.biancheng.net/python/try_except/
  • Python3 错误和异常:https://www.runoob.com/python3/python3-errors-execptions.html
  • Built-in Exceptions:https://docs.python.org/3/library/exceptions.html#exception-hierarchy
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/859354.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号