Exception Handling

本章中描述的Function将使您能够处理和引发 Python 异常。了解 Python 异常处理的一些基础知识很重要。它的工作原理类似于 Unix errno变量:全局指示器(每个线程)指示最近发生的错误。大多数Function不会在成功时清除此错误,但会设置它以指示失败时错误的原因。大多数函数还会返回错误指示符,如果应该返回指针,则通常为* NULL *;如果返回整数,则通常为-1(exceptions:PyArg_*()函数返回1表示成功,0表示失败)。

当某个函数由于某个函数调用失败而必须失败时,通常不会设置错误指示符。它调用的Function已经设置好了。它负责处理错误并清除异常,或者负责清除其拥有的任何资源(例如对象引用或内存分配)后返回;如果它没有准备好处理错误,则应该continue 正常运行。如果由于错误而返回,则重要的是向呼叫者表明已设置了错误。如果未处理或未认真传播错误,则对 Python/C API 的其他调用可能无法正常运行,并且可能会以神秘方式失败。

错误指示符由与 Python 变量sys.exc_typesys.exc_valuesys.exc_traceback对应的三个 Python 对象组成。存在 API 函数以各种方式与错误指示符进行交互。每个线程都有一个单独的错误指示器。

设置错误指示器后,仅**调用此函数。否则会导致致命错误!

如果* set_sys_last_vars *不为零,则变量sys.last_typesys.last_valuesys.last_traceback将分别设置为打印异常的类型,值和回溯。

测试是否设置了错误指示器。如果设置,则返回异常* type (对PyErr_Set*()函数之一或PyErr_Restore()的最后一次调用的第一个参数)。如果未设置,则返回 NULL *。您没有对返回值的引用,因此不需要Py_DECREF()

Note

不要将返回值与特定异常进行比较;改为使用PyErr_ExceptionMatches(),如下所示。 (比较很容易失败,因为在类异常的情况下,异常可能是实例而不是类,或者可能是预期异常的子类.)

Note

此Function通常仅由需要处理异常的代码或需要临时保存和恢复错误指示符的代码使用。

Note

此Function通常仅用于需要临时保存和恢复错误指示符的代码。使用PyErr_Fetch()保存当前的异常状态。

此函数设置错误指示符并返回* NULL *。 * exception *应该是 Python 异常类。 * format *和后续参数有助于格式化错误消息;它们的含义和值与PyString_FromFormat()相同。

这是PyErr_SetNone(PyExc_MemoryError)的简写;它返回* NULL *,因此对象分配函数在内存不足时可以写入return PyErr_NoMemory();

这是一个便利函数,可在 C 库函数返回错误并设置 C 变量errno时引发异常。它构造一个 Tuples 对象,其第一项是整数errno值,而第二项是相应的错误消息(从strerror()得到),然后调用PyErr_SetObject(type, object)。在 Unix 上,当errno值为EINTR时(表示系统调用已break),它将调用PyErr_CheckSignals(),如果设置了错误指示符,则将其设置为该值。该函数始终返回* NULL *,因此当系统调用返回错误时,围绕系统调用的包装器函数可以写入return PyErr_SetFromErrno(type);

PyErr_SetFromErrnoWithFilenameObject()相似,但文件名以 C 字符串形式给出。

这是提高WindowsError的便捷Function。如果以0的* ierr 进行调用,则会使用GetLastError()的调用返回的错误代码。它调用 Win32 函数FormatMessage()来检索 ierr GetLastError()给定的错误代码的 Windows 描述,然后构造一个 Tuples 对象,其第一项为 ierr 值,第二项为相应的错误消息(从FormatMessage()得到),然后调用PyErr_SetObject(PyExc_WindowsError, object)。此函数始终返回 NULL *。可用性:Windows。

PyErr_SetFromWindowsErr()相似,带有一个附加参数,指定要引发的异常类型。可用性:Windows。

2.3 版的新Function。

PyErr_SetFromWindowsErrWithFilenameObject()相似,但文件名以 C 字符串形式给出。可用性:Windows。

2.3 版的新Function。

PyErr_SetFromWindowsErrWithFilename()相似,带有一个附加参数,指定要引发的异常类型。可用性:Windows。

2.3 版的新Function。

此Function通常将警告消息打印到* sys.stderr *;但是,用户也可能已指定警告将变为错误,在这种情况下,这将引发异常。由于警告机制存在问题,该函数还可能引发异常(该实现会导入warnings模块来执行繁重的工作)。如果未引发异常,则返回值为0;如果引发异常,则返回值为-1。 (无法确定是否实际打印警告消息,也不知道异常的原因;这是有意的.)如果引发异常,则调用方应执行其常规异常处理(例如,Py_DECREF()拥有的引用)并返回错误值)。

警告类别必须是PyExc_Warning的子类; PyExc_WarningPyExc_Exception的子类;默认警告类别为PyExc_RuntimeWarning。标准的 Python 警告类别可用作全局变量,其名称在标准警告类别处枚举。

有关警告控制的信息,请参阅命令行文档中warnings模块的文档和-W选项。没有用于警告控制的 C API。

不推荐使用;请改用PyErr_WarnEx()

2.6 版的新Function。

2.6 版的新Function。

该 Util 函数创建并返回一个新的异常类。 * name *参数必须是新异常的名称,格式为module.classname的 C 字符串。 * base dict 参数通常是 NULL *。这将创建一个从Exception派生的类对象(在 C 中可以passPyExc_Exception访问)。

新类的__module__属性设置为* name *参数的第一部分(直到最后一个点),而类名则设置为最后一部分(在最后一个点之后)。 * base *参数可用于指定备用 Base Class;它既可以是一个类,也可以是一组 Tuples。 * dict *参数可用于指定类变量和方法的字典。

PyErr_NewException()相同,不同之处在于可以轻松为新的异常类提供 docstring:如果* doc 为非 NULL *,它将用作异常类的 docstring。

2.7 版的新Function。

该函数使用单个参数* obj 进行调用,该参数标识发生了无法提出的异常的上下文。如果可能, obj *的代表将打印在警告消息中。

Unicode 异常对象

以下函数用于从 C 创建和修改 Unicode 异常。

Recursion Control

这两个函数提供了一种在核心和扩展模块中以 C 级别执行安全递归调用的方法。如果递归代码不一定调用 Python 代码(自动跟踪其递归深度),则需要使用它们。

如果定义了USE_STACKCHECK,则此函数使用PyOS_CheckStack()检查 os 堆栈是否溢出。在这种情况下,它将设置MemoryError并返回非零值。

然后,该函数检查是否达到了递归限制。在这种情况下,将设置RuntimeError并返回非零值。否则,返回零。

Standard Exceptions

所有标准 Python 异常都可以用作全局变量,其名称为PyExc_,后跟 Python 异常名称。它们的类型为PyObject*;它们都是类对象。为了完整起见,以下是所有变量:

C Name Python Name Notes
PyExc_BaseException BaseException (1), (4)
PyExc_Exception Exception (1)
PyExc_StandardError StandardError (1)
PyExc_ArithmeticError ArithmeticError (1)
PyExc_AssertionError AssertionError
PyExc_AttributeError AttributeError
PyExc_BufferError BufferError
PyExc_EnvironmentError EnvironmentError (1)
PyExc_EOFError EOFError
PyExc_FloatingPointError FloatingPointError
PyExc_GeneratorExit GeneratorExit
PyExc_ImportError ImportError
PyExc_IndentationError IndentationError
PyExc_IndexError IndexError
PyExc_IOError IOError
PyExc_KeyError KeyError
PyExc_KeyboardInterrupt KeyboardInterrupt
PyExc_LookupError LookupError (1)
PyExc_MemoryError MemoryError
PyExc_NameError NameError
PyExc_NotImplementedError NotImplementedError
PyExc_OSError OSError
PyExc_OverflowError OverflowError
PyExc_ReferenceError ReferenceError (2)
PyExc_RuntimeError RuntimeError
PyExc_StopIteration StopIteration
PyExc_SyntaxError SyntaxError
PyExc_SystemError SystemError
PyExc_SystemExit SystemExit
PyExc_TabError TabError
PyExc_TypeError TypeError
PyExc_UnboundLocalError UnboundLocalError
PyExc_UnicodeDecodeError UnicodeDecodeError
PyExc_UnicodeEncodeError UnicodeEncodeError
PyExc_UnicodeError UnicodeError
PyExc_UnicodeTranslateError UnicodeTranslateError
PyExc_VMSError VMSError (5)
PyExc_ValueError ValueError
PyExc_WindowsError WindowsError (3)
PyExc_ZeroDivisionError ZeroDivisionError

Notes:

标准警告类别

所有标准的 Python 警告类别都可以用作全局变量,其名称为PyExc_,后跟 Python 异常名称。它们的类型为PyObject*;它们都是类对象。为了完整起见,以下是所有变量:

C Name Python Name Notes
PyExc_Warning Warning (1)
PyExc_BytesWarning BytesWarning
PyExc_DeprecationWarning DeprecationWarning
PyExc_FutureWarning FutureWarning
PyExc_ImportWarning ImportWarning
PyExc_PendingDeprecationWarning PendingDeprecationWarning
PyExc_RuntimeWarning RuntimeWarning
PyExc_SyntaxWarning SyntaxWarning
PyExc_UnicodeWarning UnicodeWarning
PyExc_UserWarning UserWarning

Notes:

String Exceptions

在 2.6 版中更改:引发或捕获的所有异常都必须来自BaseException。现在try引发字符串异常会引发TypeError

首页