异常处理

本章中描述的函数将允许您处理和引发Python异常。了解Python异常处理的一些基础知识是很重要的。它的工作方式有点像POSIX errno 变量:存在上一个错误的全局指示器(每个线程)。大多数C API函数在成功时不清除此项,但会将其设置为指示失败时出错的原因。大多数C API函数还返回一个错误指示器,通常 NULL 如果他们应该返回一个指针,或者 -1 如果它们返回一个整数(异常: PyArg_* 函数返回 1 为了成功和 0 为了失败)。

具体来说,错误指示器由三个对象指针组成:异常的类型、异常的值和回溯对象。任何一个指针都可以是 NULL 如果未设置(尽管禁止某些组合,例如,如果异常类型为 NULL

当一个函数因为它调用的某个函数失败而必须失败时,它通常不设置错误指示器;它调用的函数已经设置了它。它负责处理错误和清除异常,或者在清理它所拥有的任何资源(如对象引用或内存分配)后返回;它应该 not 如果不准备处理错误,则正常继续。如果由于错误返回,则必须向调用方指示已设置错误。如果错误没有得到处理或仔细传播,那么对python/c api的额外调用可能不会按预期的方式运行,并且可能以神秘的方式失败。

注解

错误指示器是 not 结果 sys.exc_info() .前者对应一个尚未捕获(因此仍在传播)的异常,而后者在捕获后返回一个异常(因此已停止传播)。

打印和清除

void PyErr_Clear()

清除错误指示灯。如果没有设置错误指示器,则没有效果。

void PyErr_PrintEx(int set_sys_last_vars)

打印标准回溯到 sys.stderr 并清除错误指示灯。 除非 错误是 SystemExit ,在这种情况下,不会打印任何跟踪,而python进程将退出,并返回由 SystemExit 实例。

调用此函数 only 当设置错误指示器时。否则将导致致命错误!

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

void PyErr_Print()

Alias PyErr_PrintEx(1) .

void PyErr_WriteUnraisable(PyObject *obj)

呼叫 sys.unraisablehook() 使用当前异常和 obj 参数。

此实用程序函数将警告消息打印到 sys.stderr 当设置了异常,但解释程序无法实际引发异常时。例如,当 __del__() 方法。

用单个参数调用函数 obj 它标识发生无法判断异常的上下文。如果可能,代表 obj 将在警告消息中打印。

调用此函数时必须设置异常。

引发异常

这些函数帮助您设置当前线程的错误指示器。为了方便起见,这些函数中的一些总是返回 NULL 用于 return 语句。

void PyErr_SetString(PyObject *type, const char *message)

这是设置错误指示器的最常见方法。第一个参数指定异常类型;它通常是标准异常之一,例如 PyExc_RuntimeError . 您不需要增加它的引用计数。第二个参数是错误消息;它是从 'utf-8 '.

void PyErr_SetObject(PyObject *type, PyObject *value)

此功能类似于 PyErr_SetString() 但允许您为异常的“值”指定任意的python对象。

PyObject *PyErr_Format(PyObject *exception, const char *format, ...)
Return value: Always NULL.

此函数设置错误指示器并返回 NULL . 例外 应该是python异常类。这个 格式 后续参数有助于格式化错误消息;它们的含义和值与中的相同。 PyUnicode_FromFormat() . 格式 是一个ASCII编码字符串。

PyObject *PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
Return value: Always NULL.

等同于 PyErr_Format() 但拿一个 va_list 参数而不是可变数量的参数。

3.5 新版功能.

void PyErr_SetNone(PyObject *type)

这是 PyErr_SetObject(type, Py_None) .

int PyErr_BadArgument()

这是 PyErr_SetString(PyExc_TypeError, message) 在哪里 消息 指示使用非法参数调用了内置操作。主要供内部使用。

PyObject *PyErr_NoMemory()
Return value: Always NULL.

这是 PyErr_SetNone(PyExc_MemoryError) 它回来了 NULL 因此对象分配函数可以写入 return PyErr_NoMemory(); 当内存耗尽时。

PyObject *PyErr_SetFromErrno(PyObject *type)
Return value: Always NULL.

这是一个方便的函数,用于在C库函数返回错误并设置C变量时引发异常。 errno . 它构造一个tuple对象,其第一个项是整数 errno 值,其第二项是相应的错误消息(从 strerror() ,然后呼叫 PyErr_SetObject(type, object) . 在Unix上,当 errno 价值是 EINTR ,表示中断的系统调用,此调用 PyErr_CheckSignals() 如果设置了错误指示器,则将其设置为该值。函数总是返回 NULL ,因此系统调用周围的包装函数可以写入 return PyErr_SetFromErrno(type); 当系统调用返回错误时。

PyObject *PyErr_SetFromErrnoWithFilenameObject(PyObject *type, PyObject *filenameObject)
Return value: Always NULL.

类似 PyErr_SetFromErrno() ,如果 文件名对象 不是 NULL ,传递给的构造函数 type 作为第三个参数。在情况下 OSError 异常,用于定义 filename 异常实例的属性。

PyObject *PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)
Return value: Always NULL.

类似 PyErr_SetFromErrnoWithFilenameObject() ,但采用第二个文件名对象,用于在采用两个文件名的函数失败时引发错误。

3.4 新版功能.

PyObject *PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)
Return value: Always NULL.

类似于 PyErr_SetFromErrnoWithFilenameObject() ,但文件名以C字符串形式给出。 文件名 是从 filesystem encoding and error handler

PyObject *PyErr_SetFromWindowsErr(int ierr)
Return value: Always NULL.

这是一个方便提升的功能 WindowsError . 如果被调用 ierr 属于 0 ,调用返回的错误代码 GetLastError() 而是使用。它调用win32函数 FormatMessage() 检索Windows对错误代码的描述 ierrGetLastError() ,然后构造一个tuple对象,其第一个项是 ierr 值,其第二项是相应的错误消息(从 FormatMessage() ,然后呼叫 PyErr_SetObject(PyExc_WindowsError, object) . 此函数始终返回 NULL .

Availability :Windows。

PyObject *PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)
Return value: Always NULL.

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

Availability :Windows。

PyObject *PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)
Return value: Always NULL.

类似 PyErr_SetFromWindowsErrWithFilenameObject() ,但文件名以C字符串形式给出。 filename 从文件系统编码中解码 (os.fsdecode()

Availability :Windows。

PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)
Return value: Always NULL.

类似 PyErr_SetFromWindowsErrWithFilenameObject() ,带有一个指定要引发的异常类型的附加参数。

Availability :Windows。

PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)
Return value: Always NULL.

类似 PyErr_SetExcFromWindowsErrWithFilenameObject() ,但接受第二个文件名对象。

Availability :Windows。

3.4 新版功能.

PyObject *PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename)
Return value: Always NULL.

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

Availability :Windows。

PyObject *PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
Return value: Always NULL.

这是一个方便引发的功能 ImportError . msg 将设置为异常的消息字符串。 namepath ,两者都可以 NULL ,将设置为 ImportError 各自 namepath 属性。

3.3 新版功能.

void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)

设置当前异常的文件、行和偏移量信息。如果当前异常不是 SyntaxError ,然后设置其他属性,使异常打印子系统认为异常是 SyntaxError .

3.4 新版功能.

void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)

喜欢 PyErr_SyntaxLocationObject() ,但是 文件名 是从 filesystem encoding and error handler

3.2 新版功能.

void PyErr_SyntaxLocation(const char *filename, int lineno)

类似于 PyErr_SyntaxLocationEx() ,但col_offset参数被省略。

void PyErr_BadInternalCall()

这是 PyErr_SetString(PyExc_SystemError, message) 在哪里 消息 指示使用非法参数调用了内部操作(例如python/c api函数)。主要供内部使用。

发出警告

使用这些函数从C代码发出警告。它们镜像了由python导出的类似函数 warnings 模块。他们通常会将警告信息打印到 sys.stderr ;但是,用户也可能指定将警告转换为错误,在这种情况下,它们将引发异常。由于警报机器出现问题,这些功能也可能引发异常。返回值为 0 如果未引发异常,或 -1 如果引发异常。(无法确定警告消息是否实际打印,也无法确定异常的原因;这是故意的。)如果引发异常,调用方应执行其正常的异常处理(例如, Py_DECREF() 拥有引用并返回错误值)。

int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)

发出警告消息。这个 类别 参数是警告类别(见下文)或 NULL消息 参数是一个UTF-8编码的字符串。 stack_level 是一个正数,给出了许多堆栈帧;将从该堆栈帧中当前正在执行的代码行发出警告。一 stack_level 其中1是函数调用 PyErr_WarnEx() ,2是上面的函数,依此类推。

警告类别必须是的子类 PyExc_WarningPyExc_Warning 是的子类 PyExc_Exception ;默认警告类别为 PyExc_RuntimeWarning . 标准的python警告类别可用作全局变量,其名称枚举在 标准警告类别 .

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

PyObject *PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
Return value: Always NULL.

很像 PyErr_SetImportError() 但是这个函数允许指定 ImportError 提高。

3.6 新版功能.

int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)

发出对所有警告属性具有显式控制的警告消息。这是一个围绕python函数的简单包装器 warnings.warn_explicit() ,有关详细信息,请参阅。这个 模块登记处 参数可以设置为 NULL 以获得此处描述的默认效果。

3.4 新版功能.

int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)

类似于 PyErr_WarnExplicitObject() 除了那个 消息模块 是UTF-8编码的字符串,并且 文件名 是从 filesystem encoding and error handler

int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)

功能类似于 PyErr_WarnEx() ,但使用 PyUnicode_FromFormat() 设置警告消息的格式。 格式 是一个ASCII编码字符串。

3.2 新版功能.

int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)

功能类似于 PyErr_WarnFormat() ,但是 类别ResourceWarning 就这样过去了 来源warnings.WarningMessage() .

3.6 新版功能.

查询错误指示器

PyObject *PyErr_Occurred()
Return value: Borrowed reference.

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

打电话的人必须拿着电话。

注解

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

int PyErr_ExceptionMatches(PyObject *exc)

相当于 PyErr_GivenExceptionMatches(PyErr_Occurred(), exc) . 只有在实际设置异常时才应调用此函数;如果没有引发异常,则会发生内存访问冲突。

int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)

如果 鉴于 异常与中的异常类型匹配 exc . 如果 exc 是类对象,当 鉴于 是子类的实例。如果 exc 是一个元组,将搜索该元组中的所有异常类型(以及子元组中的递归类型)以查找匹配项。

void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

将错误指示器检索到三个变量中,这些变量的地址将被传递。如果未设置错误指示器,则将所有三个变量都设置为 NULL . 如果设置了它,它将被清除,并且您拥有对检索到的每个对象的引用。值和回溯对象可以是 NULL 即使类型对象不是。

注解

此函数通常只用于需要捕获异常的代码或需要临时保存和恢复错误指示器的代码,例如:

{
   PyObject *type, *value, *traceback;
   PyErr_Fetch(&type, &value, &traceback);

   /* ... code that might produce other errors ... */

   PyErr_Restore(type, value, traceback);
}
void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)

从三个对象中设置错误指示器。如果错误指示灯已设置,则首先清除。如果对象是 NULL ,错误指示灯被清除。不要通过 NULL 类型和非-``NULL``值或回溯。异常类型应为类。不要传递无效的异常类型或值。(违反这些规则将在以后引起微妙的问题。)此调用会带走对每个对象的引用:必须在调用之前拥有对每个对象的引用,并且在调用之后,您不再拥有这些引用。(如果你不理解这个,不要使用这个函数。我警告过你。)

注解

此功能通常仅用于需要临时保存和恢复错误指示器的代码。使用 PyErr_Fetch() 保存当前错误指示器。

void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)

在某些情况下,返回的值 PyErr_Fetch() 下面可以是“未规范化”,意思是 *exc 是类对象,但 *val 不是同一类的实例。在这种情况下,这个函数可以用来实例化类。如果值已经被规范化,则不会发生任何事情。为了提高性能,实现了延迟的规范化。

注解

这个函数 隐式设置 __traceback__ 异常值的属性。如果需要适当地设置跟踪,则需要以下附加代码段:

if (tb != NULL) {
  PyException_SetTraceback(val, tb);
}
void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

从中检索异常信息 sys.exc_info() . 这指的是一个例外 已经抓到 也不例外。返回三个对象的新引用,其中任何一个对象 NULL . 不修改异常信息状态。

注解

想要处理异常的代码通常不使用此函数。相反,它可以在代码需要临时保存和恢复异常状态时使用。使用 PyErr_SetExcInfo() 恢复或清除异常状态。

3.3 新版功能.

void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)

设置异常信息,如从 sys.exc_info() . 这指的是一个例外 已经抓到 也不例外。此函数窃取参数的引用。要清除异常状态,请通过 NULL 三个论点。有关三个参数的一般规则,请参见 PyErr_Restore() .

注解

想要处理异常的代码通常不使用此函数。相反,它可以在代码需要临时保存和恢复异常状态时使用。使用 PyErr_GetExcInfo() 读取异常状态。

3.3 新版功能.

信号处理

int PyErr_CheckSignals()

此函数与Python的信号处理交互。它检查信号是否已发送到进程,如果已发送,则调用相应的信号处理程序。如果 signal 支持模块,可以调用用python编写的信号处理程序。在所有情况下, SIGINT 是提高 KeyboardInterrupt 例外。如果引发异常,则设置错误指示器并返回函数 -1 ;否则函数返回 0 . 如果之前设置了错误指示灯,则可以清除错误指示灯,也可以不清除错误指示灯。

void PyErr_SetInterrupt()

模拟 SIGINT 信号到达。下次 PyErr_CheckSignals() 调用的python信号处理程序 SIGINT 将被调用。

如果 SIGINT 不是由python处理的(它被设置为 signal.SIG_DFLsignal.SIG_IGN ,此函数不起作用。

int PySignal_SetWakeupFd(int fd)

此实用程序函数指定一个文件描述符,每当接收到信号时,该文件描述符将信号号作为单个字节写入其中。 fd 必须是非阻塞的。它返回前一个这样的文件描述符。

价值 -1 禁用该功能;这是初始状态。这相当于 signal.set_wakeup_fd() 在python中,但是没有任何错误检查。 fd 应该是有效的文件描述符。只能从主线程调用函数。

在 3.5 版更改: 在Windows上,该函数现在还支持套接字句柄。

异常类

PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
Return value: New reference.

此实用程序函数创建并返回一个新的异常类。这个 name 参数必须是新异常的名称,窗体的C字符串 module.classname . 这个 basedict 参数通常为 NULL . 这将创建一个派生自 Exception (可在C中访问为 PyExc_Exception

这个 __module__ 新类的属性设置为 name 参数,类名设置为最后一部分(在最后一个点之后)。这个 base 参数可用于指定备用基类;它只能是一个类或一个类的元组。这个 dict 参数可用于指定类变量和方法的字典。

PyObject *PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
Return value: New reference.

等同于 PyErr_NewException() ,但新的异常类很容易被赋予docstring:if doc 是非-``NULL`,它将用作异常类的docstring。

3.2 新版功能.

异常对象

PyObject *PyException_GetTraceback(PyObject *ex)
Return value: New reference.

将与异常关联的回溯作为新引用返回,从python到 __traceback__ . 如果没有关联的回溯,则返回 NULL .

int PyException_SetTraceback(PyObject *ex, PyObject *tb)

将与异常关联的回溯设置为 tb . 使用 Py_None 清除它。

PyObject *PyException_GetContext(PyObject *ex)
Return value: New reference.

返回上下文(处理期间的另一个异常实例 ex 引发)作为新引用与异常关联,可从python通过 __context__ . 如果没有关联的上下文,则返回 NULL .

void PyException_SetContext(PyObject *ex, PyObject *ctx)

将与异常关联的上下文设置为 ctx . 使用 NULL 清除它。没有类型检查以确保 ctx 是异常实例。这偷了一个参考 ctx .

PyObject *PyException_GetCause(PyObject *ex)
Return value: New reference.

返回原因(异常实例,或 None ,由 raise ... from ... )作为新的引用与异常关联,通过 __cause__ .

void PyException_SetCause(PyObject *ex, PyObject *cause)

将与异常关联的原因设置为 原因 . 使用 NULL 清除它。没有类型检查以确保 原因 是异常实例或 None . 这偷了一个参考 原因 .

__suppress_context__ 隐式设置为 True 通过这个函数。

Unicode异常对象

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

PyObject *PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Return value: New reference.

创建一个 UnicodeDecodeError 具有属性的对象 encodingobject长度开始end原因 . encoding原因 是UTF-8编码的字符串。

PyObject *PyUnicodeEncodeError_Create(const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Return value: New reference.

创建一个 UnicodeEncodeError 具有属性的对象 encodingobject长度开始end原因 . encoding原因 是UTF-8编码的字符串。

3.3 版后已移除: 3.11

Py_UNICODE 自Python3.3以来已弃用。请迁移到 PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns", ...) .

PyObject *PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
Return value: New reference.

创建一个 UnicodeTranslateError 具有属性的对象 object长度开始end原因 . 原因 是一个UTF-8编码字符串。

3.3 版后已移除: 3.11

Py_UNICODE 自Python3.3以来已弃用。请迁移到 PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", ...) .

PyObject *PyUnicodeDecodeError_GetEncoding(PyObject *exc)
PyObject *PyUnicodeEncodeError_GetEncoding(PyObject *exc)
Return value: New reference.

返回 encoding 给定异常对象的属性。

PyObject *PyUnicodeDecodeError_GetObject(PyObject *exc)
PyObject *PyUnicodeEncodeError_GetObject(PyObject *exc)
PyObject *PyUnicodeTranslateError_GetObject(PyObject *exc)
Return value: New reference.

返回 object 给定异常对象的属性。

int PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)

得到 开始 给定异常对象的属性并将其放入 *start . 开始 不得 NULL . 返回 0 关于成功, -1 失败论。

int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)

设置 开始 给定异常对象的属性 开始 . 返回 0 关于成功, -1 失败论。

int PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)

得到 end 给定异常对象的属性并将其放入 *end . end 不得 NULL . 返回 0 关于成功, -1 失败论。

int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)

设置 end 给定异常对象的属性 end . 返回 0 关于成功, -1 失败论。

PyObject *PyUnicodeDecodeError_GetReason(PyObject *exc)
PyObject *PyUnicodeEncodeError_GetReason(PyObject *exc)
PyObject *PyUnicodeTranslateError_GetReason(PyObject *exc)
Return value: New reference.

返回 原因 给定异常对象的属性。

int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)

设置 原因 给定异常对象的属性 原因 . 返回 0 关于成功, -1 失败论。

递归控件

这两个函数提供了在核心模块和扩展模块中在C级别执行安全递归调用的方法。如果递归代码不一定调用Python代码(它会自动跟踪递归深度),则需要它们。它们也不需要 tp_call 实现,因为 call protocol 负责递归处理。

int Py_EnterRecursiveCall(const char *where)

标记将要执行递归C级调用的点。

如果 USE_STACKCHECK 定义,此函数检查操作系统堆栈是否溢出 PyOS_CheckStack() . 在这种情况下,它设置了 MemoryError 并返回一个非零值。

然后,函数检查是否达到递归限制。如果是这样的话, RecursionError 设置并返回非零值。否则,返回零。

在哪里? 应该是UTF-8编码的字符串,例如 " in instance check" 连接到 RecursionError 递归深度限制导致的消息。

在 3.9 版更改: 这个函数现在也可以在有限的API中使用。

void Py_LeaveRecursiveCall(void)

结束A Py_EnterRecursiveCall() . 必须为每个调用一次 成功的 调用 Py_EnterRecursiveCall() .

在 3.9 版更改: 这个函数现在也可以在有限的API中使用。

正确实施 tp_repr 对于容器类型,需要特殊的递归处理。除了保护堆栈之外, tp_repr 还需要跟踪对象以防止循环。以下两个功能有助于实现此功能。实际上,这些是c等价于 reprlib.recursive_repr() .

int Py_ReprEnter(PyObject *object)

tp_repr 实现检测周期。

如果对象已被处理,函数将返回一个正整数。在这种情况下, tp_repr 实现应返回一个指示循环的字符串对象。作为例子, dict 对象返回 {{...}}list 对象返回 [...] .

如果达到递归限制,函数将返回一个负整数。在这种情况下, tp_repr 执行通常应返回 NULL .

否则,函数返回零, tp_repr 执行可以正常继续。

void Py_ReprLeave(PyObject *object)

结束A Py_ReprEnter() . 每次调用时必须调用一次 Py_ReprEnter() 返回零。

标准例外

所有标准python异常都可用作全局变量,其名称为 PyExc_ 后跟python异常名称。这些是那种 PyObject* 它们都是类对象。为了完整性,以下是所有变量:

C名

Python 名称

笔记

PyExc_BaseException

BaseException

(1)

PyExc_Exception

Exception

(1)

PyExc_ArithmeticError

ArithmeticError

(1)

PyExc_AssertionError

AssertionError

PyExc_AttributeError

AttributeError

PyExc_BlockingIOError

BlockingIOError

PyExc_BrokenPipeError

BrokenPipeError

PyExc_BufferError

BufferError

PyExc_ChildProcessError

ChildProcessError

PyExc_ConnectionAbortedError

ConnectionAbortedError

PyExc_ConnectionError

ConnectionError

PyExc_ConnectionRefusedError

ConnectionRefusedError

PyExc_ConnectionResetError

ConnectionResetError

PyExc_EOFError

EOFError

PyExc_FileExistsError

FileExistsError

PyExc_FileNotFoundError

FileNotFoundError

PyExc_FloatingPointError

FloatingPointError

PyExc_GeneratorExit

GeneratorExit

PyExc_ImportError

ImportError

PyExc_IndentationError

IndentationError

PyExc_IndexError

IndexError

PyExc_InterruptedError

InterruptedError

PyExc_IsADirectoryError

IsADirectoryError

PyExc_KeyError

KeyError

PyExc_KeyboardInterrupt

KeyboardInterrupt

PyExc_LookupError

LookupError

(1)

PyExc_MemoryError

MemoryError

PyExc_ModuleNotFoundError

ModuleNotFoundError

PyExc_NameError

NameError

PyExc_NotADirectoryError

NotADirectoryError

PyExc_NotImplementedError

NotImplementedError

PyExc_OSError

OSError

(1)

PyExc_OverflowError

OverflowError

PyExc_PermissionError

PermissionError

PyExc_ProcessLookupError

ProcessLookupError

PyExc_RecursionError

RecursionError

PyExc_ReferenceError

ReferenceError

(2)

PyExc_RuntimeError

RuntimeError

PyExc_StopAsyncIteration

StopAsyncIteration

PyExc_StopIteration

StopIteration

PyExc_SyntaxError

SyntaxError

PyExc_SystemError

SystemError

PyExc_SystemExit

SystemExit

PyExc_TabError

TabError

PyExc_TimeoutError

TimeoutError

PyExc_TypeError

TypeError

PyExc_UnboundLocalError

UnboundLocalError

PyExc_UnicodeDecodeError

UnicodeDecodeError

PyExc_UnicodeEncodeError

UnicodeEncodeError

PyExc_UnicodeError

UnicodeError

PyExc_UnicodeTranslateError

UnicodeTranslateError

PyExc_ValueError

ValueError

PyExc_ZeroDivisionError

ZeroDivisionError

3.3 新版功能: PyExc_BlockingIOErrorPyExc_BrokenPipeErrorPyExc_ChildProcessErrorPyExc_ConnectionErrorPyExc_ConnectionAbortedErrorPyExc_ConnectionRefusedErrorPyExc_ConnectionResetErrorPyExc_FileExistsErrorPyExc_FileNotFoundErrorPyExc_InterruptedErrorPyExc_IsADirectoryErrorPyExc_NotADirectoryErrorPyExc_PermissionErrorPyExc_ProcessLookupErrorPyExc_TimeoutError 介绍如下 PEP 3151 .

3.5 新版功能: PyExc_StopAsyncIterationPyExc_RecursionError .

3.6 新版功能: PyExc_ModuleNotFoundError .

这些是兼容性别名 PyExc_OSError

C名

笔记

PyExc_EnvironmentError

PyExc_IOError

PyExc_WindowsError

(3)

在 3.3 版更改: 这些别名过去是单独的异常类型。

笔记:

  1. 这是其他标准异常的基类。

  2. 仅在Windows上定义;通过测试预处理器宏来保护使用此函数的代码 MS_WINDOWS 定义。

标准警告类别

所有标准的python警告类别都可用作全局变量,其名称为 PyExc_ 后跟python异常名称。这些是那种 PyObject* 它们都是类对象。为了完整性,以下是所有变量:

C名

Python 名称

笔记

PyExc_Warning

Warning

(1)

PyExc_BytesWarning

BytesWarning

PyExc_DeprecationWarning

DeprecationWarning

PyExc_FutureWarning

FutureWarning

PyExc_ImportWarning

ImportWarning

PyExc_PendingDeprecationWarning

PendingDeprecationWarning

PyExc_ResourceWarning

ResourceWarning

PyExc_RuntimeWarning

RuntimeWarning

PyExc_SyntaxWarning

SyntaxWarning

PyExc_UnicodeWarning

UnicodeWarning

PyExc_UserWarning

UserWarning

3.2 新版功能: PyExc_ResourceWarning .

笔记:

  1. 这是其他标准警告类别的基类。