Python中的错误处理和记录

在软件开发中,可能会发生不同类型的错误。 它们可能是语法错误,逻辑错误或运行时错误。

语法错误很可能在初始开发阶段发生,并且是由于语法不正确造成的。 编译该程序以执行时,很容易发现语法错误。

另一方面,逻辑错误是逻辑执行不正确的结果。 一个示例是假定未排序列表被排序的程序访问该列表。 逻辑错误是最难跟踪的错误。

如果我们不考虑所有极端情况,则运行时错误是最有趣的错误。 一个示例将尝试访问不存在的文件。

在本教程中,我们将学习如何使用Python处理错误以及如何记录错误,以更好地了解应用程序内部的错误。

在Python中处理异常

让我们从一个简单的程序开始,在Python中添加两个数字。 我们的程序接受两个参数作为输入并打印总和。 这是一个添加两个数字的Python程序:

def addNumbers(a, b):
    print a + b

addNumbers(5, 10)

尝试运行上面的Python程序,您应该打印出总和。

15

在编写上述程序时,我们并未真正考虑到任何事情都会出错的事实。 如果传递的参数之一不是数字怎么办?

addNumbers('', 10)

我们尚未处理这种情况,因此我们的程序将崩溃并显示以下错误消息:

Traceback (most recent call last):
  File "addNumber.py", line 4, in <module>
    addNumbers('', 10)
  File "addNumber.py", line 2, in addNumbers
    print a + b
TypeError: cannot concatenate 'str' and 'int' objects

我们可以通过检查传递的参数是否为整数来解决上述问题。 但这无法解决问题。 如果代码由于其他原因而崩溃并导致程序崩溃怎么办? 使用遇到错误而崩溃的程序不是一个好主意。 即使遇到未知错误,代码也应足够健壮以优雅地处理崩溃并让用户知道出了点问题。

使用try和except处理异常

在Python中,我们使用tryexcept语句来处理异常。 每当代码崩溃时,都将引发异常而不会导致程序崩溃。 让我们修改加号程序,使其包含tryexcept语句。

def addNumbers(a, b):
    try:
        return a + b
    except Exception as e:
        return 'Error occurred : ' + str(e)

print addNumbers('', 10)

Python将在tryexcept语句中处理所有代码。 遇到错误时,控件将传递到except块,从而跳过两者之间的代码。

如以上代码所示,我们已将代码移至tryexcept语句内。 尝试运行该程序,它应该引发错误消息,而不是使程序崩溃。 异常原因也作为异常消息返回。

上面的方法处理意外的异常。 让我们看一下如何处理预期的异常。 假设我们正在尝试使用Python程序读取特定文件,但是该文件不存在。 在这种情况下,我们将处理异常,并让用户知道该文件发生时不存在。 看一下文件读取代码:

try:
    try:
        with open('fname') as f:
            content = f.readlines()
    except IOError as e:
        print str(e)
except Exception as e:
    print str(e)

在上面的代码中,我们已经处理了IOError异常处理程序中的文件读取。 如果代码由于文件fname不可用而中断,则该错误将在IOError处理程序内处理。 与IOError异常类似,还有很多标准异常,例如ArithmeticOverflowErrorImportError ,仅举几例。

多个例外

我们可以通过组合如下所示的标准异常来一次处理多个异常:

try:
    with open('fname') as f:
        content = f.readlines()
    printb
except (IOError,NameError) as e:
    print str(e)

上面的代码将在执行程序时IOErrorNameError异常。

finally条款

假设我们在Python程序中使用了某些资源。 在程序执行期间,它遇到错误,并且只在执行一半时执行。 在这种情况下,将不必要地占用资源。 我们可以使用finally子句清理此类资源。 看下面的代码:

try:
    filePointer = open('fname','r')
    try:
        content = filePointer.readline()
    finally:
        filePointer.close()
except IOError as e:
    print str(e)

如果在执行上述代码期间,在读取文件时引发了异常, filePointerfinally块中关闭filePointer

登录Python

当应用程序内部出现问题时,如果我们知道错误的来源,则调试起来会变得更加容易。 引发异常时,我们可以记录所需的信息以跟踪问题。 Python提供了一个简单而强大的日志记录库。 让我们看一下如何在Python中使用日志记录。

import logging

# initialize the log settings
logging.basicConfig(filename='app.log',level=logging.INFO)

try:
    logging.info('Trying to open the file')
    filePointer = open('appFile','r')
    try:
        logging.info('Trying to read the file content')
        content = filePointer.readline()
    finally:
        filePointer.close()
except IOError as e:
    logging.error('Error occurred ' + str(e))

如上面的代码所示,我们首先需要导入日志记录Python库,然后使用日志文件名和日志记录级别初始化记录器。 有五个日志记录级别:DEBUG,INFO,WARNING,ERROR和CRITICAL。 在这里,我们将日志记录级别设置为INFO,因此将记录INFO及以上日志。

获取堆栈跟踪

在上面的代码中,我们只有一个程序文件,因此更容易找出错误发生的位置。 但是,当涉及多个程序文件时我们该怎么办? 在这种情况下,获取错误的堆栈跟踪信息有助于查找错误的来源。 可以记录异常的堆栈跟踪,如下所示:

import logging

# initialize the log settings
logging.basicConfig(filename = 'app.log', level = logging.INFO)

try:
    filePointer = open('appFile','r')
    try:
        content = filePointer.readline()
    finally:
        filePointer.close()
except IOError as e:
    logging.exception(str(e))

如果尝试运行上述程序,则在引发异常时,将在日志文件中记录以下错误:

ERROR:root:[Errno 2] No such file or directory: 'appFile'
Traceback (most recent call last):
  File "readFile.py", line 7, in <module>
    filePointer = open('appFile','r')
IOError: [Errno 2] No such file or directory: 'appFile'

包起来

在本教程中,我们看到了如何开始使用Python处理错误以及如何使用日志记录模块记录错误。 我们看到了tryexceptfinally语句的用法,这在处理Python中的错误处理时非常有用。 有关更多详细信息,建议您阅读有关Logging的官方文档 。 还可以查看有关在Python中处理异常文档

请在下面的评论中告诉我们您的想法。

翻译自: https://code.tutsplus.com/tutorials/error-handling-logging-in-python--cms-27932

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值