整数对象

所有整数都实现为任意大小的“长”整数对象。

发生错误时,大多数 PyLong_As* API 返回 (return type)-1,这与数字无法区分。请使用 PyErr_Occurred() 进行区分。

type PyLongObject
受限 API 的一部分(作为不透明结构体)。

PyObject 子类型表示 Python 整数对象。

PyTypeObject PyLong_Type
作为 稳定 ABI 的一部分。

PyTypeObject 实例表示 Python 整数类型。这与 Python 层中的 int 对象相同。

int PyLong_Check(PyObject *p)

如果其参数是 PyLongObjectPyLongObject 的子类型,则返回 true。此函数始终成功。

int PyLong_CheckExact(PyObject *p)

如果其参数是 PyLongObject,但不是 PyLongObject 的子类型,则返回 true。此函数始终成功。

PyObject *PyLong_FromLong(long v)
返回值: 新引用。 稳定ABI 的一部分。

v 返回一个新的 PyLongObject 对象,失败时返回 NULL

CPython 实现细节: CPython 为所有介于 -5256 之间的整数维护一个整数对象数组。当您在此范围内创建一个 int 时,您实际上只是获得对现有对象的引用。

PyObject *PyLong_FromUnsignedLong(unsigned long v)
返回值: 新引用。 稳定ABI 的一部分。

从 C unsigned long 返回一个新的 PyLongObject 对象,失败时返回 NULL

PyObject *PyLong_FromSsize_t(Py_ssize_t v)
返回值: 新引用。 稳定ABI 的一部分。

从 C Py_ssize_t 返回一个新的 PyLongObject 对象,失败时返回 NULL

PyObject *PyLong_FromSize_t(size_t v)
返回值: 新引用。 稳定ABI 的一部分。

从 C size_t 返回一个新的 PyLongObject 对象,失败时返回 NULL

PyObject *PyLong_FromLongLong(long long v)
返回值: 新引用。 稳定ABI 的一部分。

从 C long long 返回一个新的 PyLongObject 对象,失败时返回 NULL

PyObject *PyLong_FromInt32(int32_t value)
PyObject *PyLong_FromInt64(int64_t value)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

从带符号的 C int32_tint64_t 返回一个新的 PyLongObject 对象,失败时返回 NULL 并设置异常。

在 3.14 版本加入。

PyObject *PyLong_FromUnsignedLongLong(unsigned long long v)
返回值: 新引用。 稳定ABI 的一部分。

从 C unsigned long long 返回一个新的 PyLongObject 对象,失败时返回 NULL

PyObject *PyLong_FromUInt32(uint32_t value)
PyObject *PyLong_FromUInt64(uint64_t value)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

从无符号 C uint32_tuint64_t 返回一个新的 PyLongObject 对象,失败时返回 NULL 并设置异常。

在 3.14 版本加入。

PyObject *PyLong_FromDouble(double v)
返回值: 新引用。 稳定ABI 的一部分。

v 的整数部分返回一个新的 PyLongObject 对象,失败时返回 NULL

PyObject *PyLong_FromString(const char *str, char **pend, int base)
返回值: 新引用。 稳定ABI 的一部分。

根据 str 中的字符串值返回一个新的 PyLongObject,该字符串值根据 base 中的基数进行解释,失败时返回 NULL。如果 pendNULL,则成功时 *pend 将指向 str 的末尾,错误时指向无法处理的第一个字符。如果 base0,则使用 整数字面量 定义解释 str;在这种情况下,非零十进制数中的前导零会引发 ValueError。如果 base 不为 0,则它必须介于 236 之间(包括两者)。忽略前导和尾随空白以及基数说明符后和数字之间的单个下划线。如果没有数字,或者 str 在数字和尾随空白之后没有以 NULL 结尾,则会引发 ValueError

参见

PyLong_AsNativeBytes()PyLong_FromNativeBytes() 函数可用于将 PyLongObject 转换为以 256 为基数的字节数组,或从字节数组转换而来。

PyObject *PyLong_FromUnicodeObject(PyObject *u, int base)
返回值:新引用。

将字符串 u 中的 Unicode 数字序列转换为 Python 整数值。

在 3.3 版本加入。

PyObject *PyLong_FromVoidPtr(void *p)
返回值: 新引用。 稳定ABI 的一部分。

从指针 p 创建一个 Python 整数。可以使用 PyLong_AsVoidPtr() 从结果值中检索指针值。

PyObject *PyLong_FromNativeBytes(const void *buffer, size_t n_bytes, int flags)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

buffer 的前 n_bytes 中包含的值创建一个 Python 整数,将其解释为二进制补码有符号数。

flagsPyLong_AsNativeBytes() 相同。传入 -1 将选择 CPython 编译时使用的本机字节序,并假定最高有效位是符号位。传入 Py_ASNATIVEBYTES_UNSIGNED_BUFFER 将产生与调用 PyLong_FromUnsignedNativeBytes() 相同的结果。其他标志将被忽略。

在 3.13 版本加入。

PyObject *PyLong_FromUnsignedNativeBytes(const void *buffer, size_t n_bytes, int flags)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

buffer 的前 n_bytes 中包含的值创建一个 Python 整数,将其解释为无符号数。

flagsPyLong_AsNativeBytes() 相同。传入 -1 将选择 CPython 编译时使用的本机字节序,并假定最高有效位不是符号位。除了字节序之外的其他标志都将被忽略。

在 3.13 版本加入。

long PyLong_AsLong(PyObject *obj)
作为 稳定 ABI 的一部分。

返回 obj 的 C long 表示。如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 的值超出 long 的范围,则引发 OverflowError

错误时返回 -1。使用 PyErr_Occurred() 进行区分。

3.8 版本发生变更: 使用 __index__()(如果可用)。

3.10 版本发生变更: 此函数将不再使用 __int__()

long PyLong_AS_LONG(PyObject *obj)

软弃用 的别名。与首选的 PyLong_AsLong 完全等效。特别是,它可能因 OverflowError 或其他异常而失败。

3.14 版本弃用: 该函数已软弃用。

int PyLong_AsInt(PyObject *obj)
自 3.13 版本起成为 稳定 ABI 的一部分。

类似于 PyLong_AsLong(),但将结果存储在 C int 中而不是 C long 中。

在 3.13 版本加入。

long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
作为 稳定 ABI 的一部分。

返回 obj 的 C long 表示。如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 的值大于 LONG_MAX 或小于 LONG_MIN,则将 *overflow 分别设置为 1-1,并返回 -1;否则,将 *overflow 设置为 0。如果发生任何其他异常,则将 *overflow 设置为 0 并照常返回 -1

错误时返回 -1。使用 PyErr_Occurred() 进行区分。

3.8 版本发生变更: 使用 __index__()(如果可用)。

3.10 版本发生变更: 此函数将不再使用 __int__()

long long PyLong_AsLongLong(PyObject *obj)
作为 稳定 ABI 的一部分。

返回 obj 的 C long long 表示。如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 的值超出 long long 的范围,则引发 OverflowError

错误时返回 -1。使用 PyErr_Occurred() 进行区分。

3.8 版本发生变更: 使用 __index__()(如果可用)。

3.10 版本发生变更: 此函数将不再使用 __int__()

long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow)
作为 稳定 ABI 的一部分。

返回 obj 的 C long long 表示。如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 的值大于 LLONG_MAX 或小于 LLONG_MIN,则将 *overflow 分别设置为 1-1,并返回 -1;否则,将 *overflow 设置为 0。如果发生任何其他异常,则将 *overflow 设置为 0 并照常返回 -1

错误时返回 -1。使用 PyErr_Occurred() 进行区分。

在 3.2 版本加入。

3.8 版本发生变更: 使用 __index__()(如果可用)。

3.10 版本发生变更: 此函数将不再使用 __int__()

Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)
作为 稳定 ABI 的一部分。

返回 pylong 的 C Py_ssize_t 表示。pylong 必须是 PyLongObject 的实例。

如果 pylong 的值超出 Py_ssize_t 的范围,则引发 OverflowError

错误时返回 -1。使用 PyErr_Occurred() 进行区分。

unsigned long PyLong_AsUnsignedLong(PyObject *pylong)
作为 稳定 ABI 的一部分。

返回 pylong 的 C unsigned long 表示。pylong 必须是 PyLongObject 的实例。

如果 pylong 的值超出 unsigned long 的范围,则引发 OverflowError

错误时返回 (unsigned long)-1。使用 PyErr_Occurred() 进行区分。

size_t PyLong_AsSize_t(PyObject *pylong)
作为 稳定 ABI 的一部分。

返回 pylong 的 C size_t 表示。pylong 必须是 PyLongObject 的实例。

如果 pylong 的值超出 size_t 的范围,则引发 OverflowError

错误时返回 (size_t)-1。使用 PyErr_Occurred() 进行区分。

unsigned long long PyLong_AsUnsignedLongLong(PyObject *pylong)
作为 稳定 ABI 的一部分。

返回 pylong 的 C unsigned long long 表示。pylong 必须是 PyLongObject 的实例。

如果 pylong 的值超出 unsigned long long 的范围,则引发 OverflowError

错误时返回 (unsigned long long)-1。使用 PyErr_Occurred() 进行区分。

3.1 版本发生变更: pylong 现在引发 OverflowError,而不是 TypeError

unsigned long PyLong_AsUnsignedLongMask(PyObject *obj)
作为 稳定 ABI 的一部分。

返回 obj 的 C unsigned long 表示。如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 的值超出 unsigned long 的范围,则返回该值对 ULONG_MAX + 1 的模数。

错误时返回 (unsigned long)-1。使用 PyErr_Occurred() 进行区分。

3.8 版本发生变更: 使用 __index__()(如果可用)。

3.10 版本发生变更: 此函数将不再使用 __int__()

unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj)
作为 稳定 ABI 的一部分。

返回 obj 的 C unsigned long long 表示。如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 的值超出 unsigned long long 的范围,则返回该值对 ULLONG_MAX + 1 的模数。

错误时返回 (unsigned long long)-1。使用 PyErr_Occurred() 进行区分。

3.8 版本发生变更: 使用 __index__()(如果可用)。

3.10 版本发生变更: 此函数将不再使用 __int__()

int PyLong_AsInt32(PyObject *obj, int32_t *value)
int PyLong_AsInt64(PyObject *obj, int64_t *value)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

*value 设置为 obj 的带符号 C int32_tint64_t 表示。

如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

如果 obj 值超出范围,则引发 OverflowError

成功时设置 *value 并返回 0。错误时设置异常并返回 -1

value 不得为 NULL

在 3.14 版本加入。

int PyLong_AsUInt32(PyObject *obj, uint32_t *value)
int PyLong_AsUInt64(PyObject *obj, uint64_t *value)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

*value 设置为 obj 的无符号 C uint32_tuint64_t 表示。

如果 obj 不是 PyLongObject 的实例,则首先调用其 __index__() 方法(如果存在)将其转换为 PyLongObject

成功时设置 *value 并返回 0。错误时设置异常并返回 -1

value 不得为 NULL

在 3.14 版本加入。

double PyLong_AsDouble(PyObject *pylong)
作为 稳定 ABI 的一部分。

返回 pylong 的 C double 表示。pylong 必须是 PyLongObject 的实例。

如果 pylong 的值超出 double 的范围,则引发 OverflowError

错误时返回 -1.0。使用 PyErr_Occurred() 进行区分。

void *PyLong_AsVoidPtr(PyObject *pylong)
作为 稳定 ABI 的一部分。

将 Python 整数 pylong 转换为 C void 指针。如果 pylong 无法转换,则会引发 OverflowError。这仅能保证为使用 PyLong_FromVoidPtr() 创建的值生成可用的 void 指针。

错误时返回 NULL。使用 PyErr_Occurred() 进行区分。

Py_ssize_t PyLong_AsNativeBytes(PyObject *pylong, void *buffer, Py_ssize_t n_bytes, int flags)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

将 Python 整数值 pylong 复制到大小为 n_bytes 的本机 buffer 中。flags 可以设置为 -1 以使其行为类似于 C 强制类型转换,或者设置为以下文档中的值以控制其行为。

错误时返回 -1 并引发异常。这可能发生在 pylong 无法解释为整数,或者 pylong 为负数且设置了 Py_ASNATIVEBYTES_REJECT_NEGATIVE 标志的情况下。

否则,返回存储该值所需的字节数。如果此值等于或小于 n_bytes,则整个值已被复制。缓冲区的全部 n_bytes 都被写入:较大的缓冲区将用零填充。

如果返回的值大于 n_bytes,则该值已被截断:值中最低的位(可容纳的位数)被写入,而较高的位被忽略。这与 C 风格的向下转换的典型行为匹配。

备注

溢出不被视为错误。如果返回的值大于 n_bytes,则最高有效位已被丢弃。

0 永远不会被返回。

值总是作为二进制补码复制。

使用示例

int32_t value;
Py_ssize_t bytes = PyLong_AsNativeBytes(pylong, &value, sizeof(value), -1);
if (bytes < 0) {
    // Failed. A Python exception was set with the reason.
    return NULL;
}
else if (bytes <= (Py_ssize_t)sizeof(value)) {
    // Success!
}
else {
    // Overflow occurred, but 'value' contains the truncated
    // lowest bits of pylong.
}

n_bytes 设置为零将返回足以容纳该值的缓冲区大小。这可能比技术上必要的大小要大,但不会不合理。如果 n_bytes=0buffer 可以是 NULL

备注

n_bytes=0 传递给此函数不是确定值位长度的准确方法。

要获取未知大小的整个 Python 值,可以调用该函数两次:首先确定缓冲区大小,然后填充它

// Ask how much space we need.
Py_ssize_t expected = PyLong_AsNativeBytes(pylong, NULL, 0, -1);
if (expected < 0) {
    // Failed. A Python exception was set with the reason.
    return NULL;
}
assert(expected != 0);  // Impossible per the API definition.
uint8_t *bignum = malloc(expected);
if (!bignum) {
    PyErr_SetString(PyExc_MemoryError, "bignum malloc failed.");
    return NULL;
}
// Safely get the entire value.
Py_ssize_t bytes = PyLong_AsNativeBytes(pylong, bignum, expected, -1);
if (bytes < 0) {  // Exception has been set.
    free(bignum);
    return NULL;
}
else if (bytes > expected) {  // This should not be possible.
    PyErr_SetString(PyExc_RuntimeError,
        "Unexpected bignum truncation after a size check.");
    free(bignum);
    return NULL;
}
// The expected success given the above pre-check.
// ... use bignum ...
free(bignum);

flags 可以是 -1Py_ASNATIVEBYTES_DEFAULTS)以选择最像 C 强制类型转换的默认值,也可以是下表中其他标志的组合。请注意,-1 不能与其他标志组合。

目前,-1 对应于 Py_ASNATIVEBYTES_NATIVE_ENDIAN | Py_ASNATIVEBYTES_UNSIGNED_BUFFER

Flag

Py_ASNATIVEBYTES_DEFAULTS

-1

Py_ASNATIVEBYTES_BIG_ENDIAN

0

Py_ASNATIVEBYTES_LITTLE_ENDIAN

1

Py_ASNATIVEBYTES_NATIVE_ENDIAN

3

Py_ASNATIVEBYTES_UNSIGNED_BUFFER

4

Py_ASNATIVEBYTES_REJECT_NEGATIVE

8

Py_ASNATIVEBYTES_ALLOW_INDEX

16

指定 Py_ASNATIVEBYTES_NATIVE_ENDIAN 将覆盖任何其他字节序标志。传入 2 是保留值。

默认情况下,将请求足够的缓冲区以包含符号位。例如,当将 128 转换为 n_bytes=1 时,函数将返回 2(或更多)以存储零符号位。

如果指定了 Py_ASNATIVEBYTES_UNSIGNED_BUFFER,则在大小计算中将省略零符号位。这允许,例如,128 适合单字节缓冲区。如果目标缓冲区稍后被视为有符号,则正输入值可能变为负数。请注意,该标志不影响负值的处理:对于这些值,始终请求符号位的空间。

如果指定了 Py_ASNATIVEBYTES_REJECT_NEGATIVE,则如果 pylong 为负数,则会设置异常。如果没有此标志,只要有足够的空间容纳至少一个符号位,无论是否指定了 Py_ASNATIVEBYTES_UNSIGNED_BUFFER,都将复制负值。

如果指定了 Py_ASNATIVEBYTES_ALLOW_INDEX 并传入非整数值,则将首先调用其 __index__() 方法。这可能导致 Python 代码执行并允许其他线程运行,这可能会导致其他对象或正在使用的值发生更改。当 flags-1 时,此选项未设置,非整数值将引发 TypeError

备注

在默认 flags-1,或不带 REJECT_NEGATIVEUNSIGNED_BUFFER)下,多个 Python 整数可以在不溢出的情况下映射到单个值。例如,255-1 都适合单字节缓冲区并设置其所有位。这与典型的 C 强制类型转换行为匹配。

在 3.13 版本加入。

int PyLong_GetSign(PyObject *obj, int *sign)

获取整数对象 obj 的符号。

成功时,将 *sign 设置为整数符号(零为 0,负整数为 -1,正整数为 +1),并返回 0。

失败时,返回 -1 并设置异常。如果 objPyLongObject 或其子类型,则此函数始终成功。

在 3.14 版本加入。

int PyLong_IsPositive(PyObject *obj)

检查整数对象 obj 是否为正数 (obj > 0)。

如果 objPyLongObject 的实例或其子类型,则在为正数时返回 1,否则返回 0。否则设置异常并返回 -1

在 3.14 版本加入。

int PyLong_IsNegative(PyObject *obj)

检查整数对象 obj 是否为负数 (obj < 0)。

如果 objPyLongObject 的实例或其子类型,则在为负数时返回 1,否则返回 0。否则设置异常并返回 -1

在 3.14 版本加入。

int PyLong_IsZero(PyObject *obj)

检查整数对象 obj 是否为零。

如果 objPyLongObject 的实例或其子类型,则在为零时返回 1,否则返回 0。否则设置异常并返回 -1

在 3.14 版本加入。

PyObject *PyLong_GetInfo(void)
作为 稳定 ABI 的一部分。

成功时,返回一个只读的 命名元组,其中包含有关 Python 内部整数表示的信息。有关各个字段的描述,请参阅 sys.int_info

失败时,返回 NULL 并设置异常。

在 3.1 版本加入。

int PyUnstable_Long_IsCompact(const PyLongObject *op)
这是一个不稳定 API。它可能会在次要版本中未经警告而更改。

如果 op 是紧凑的,则返回 1,否则返回 0。

此函数使对性能敏感的代码能够为小整数实现“快速路径”。对于紧凑值,请使用 PyUnstable_Long_CompactValue();对于其他值,请回退到 PyLong_As* 函数或 PyLong_AsNativeBytes()

对于大多数用户来说,加速效果预计可以忽略不计。

哪些值被认为是紧凑的,这是一个实现细节,可能会发生变化。

3.12 新版功能.

Py_ssize_t PyUnstable_Long_CompactValue(const PyLongObject *op)
这是一个不稳定 API。它可能会在次要版本中未经警告而更改。

如果 op 紧凑(由 PyUnstable_Long_IsCompact() 确定),则返回其值。

否则,返回值为未定义。

3.12 新版功能.

导出 API

在 3.14 版本加入。

struct PyLongLayout

“数字”(在 GMP 术语中为“limb”)数组的布局,用于表示任意精度整数的绝对值。

使用 PyLong_GetNativeLayout() 获取 Python int 对象的本机布局,该布局用于内部绝对值“足够大”的整数。

另请参阅 sys.int_info,它在 Python 中公开了类似的信息。

uint8_t bits_per_digit

每位数字的位数。例如,15 位数字意味着位 0-14 包含有意义的信息。

uint8_t digit_size

数字大小(以字节为单位)。例如,15 位数字至少需要 2 字节。

int8_t digits_order

数字顺序

  • 1 表示最高有效数字在前

  • -1 表示最低有效数字在前

int8_t digit_endianness

数字字节序

  • 1 表示最高有效字节在前(大端)

  • -1 表示最低有效字节在前(小端)

const PyLongLayout *PyLong_GetNativeLayout(void)

获取 Python int 对象的本机布局。

请参阅 PyLongLayout 结构体。

该函数不得在 Python 初始化之前或 Python 终结化之后调用。返回的布局在 Python 终结化之前有效。该布局对于进程中的所有 Python 子解释器都是相同的,因此可以缓存。

struct PyLongExport

Python int 对象的导出。

有两种情况

int64_t value

导出 int 对象的本机整数值。仅当 digitsNULL 时有效。

uint8_t negative

如果数字为负,则为 1,否则为 0。仅当 digits 不为 NULL 时有效。

Py_ssize_t ndigits

digits 数组中的数字数量。仅当 digits 不为 NULL 时有效。

const void *digits

无符号数字的只读数组。可以是 NULL

int PyLong_Export(PyObject *obj, PyLongExport *export_long)

导出 Python int 对象。

export_long 必须指向调用者分配的 PyLongExport 结构体。它不能是 NULL

成功时,填充 *export_long 并返回 0。错误时,设置异常并返回 -1

当不再需要导出时,必须调用 PyLong_FreeExport()

CPython 实现细节: 如果 obj 是 Python int 对象或其子类,此函数总是成功。

void PyLong_FreeExport(PyLongExport *export_long)

释放由 PyLong_Export() 创建的导出 export_long

CPython 实现细节: 如果 export_long->digitsNULL,则调用 PyLong_FreeExport() 是可选的。

PyLongWriter API

PyLongWriter API 可用于导入整数。

在 3.14 版本加入。

struct PyLongWriter

一个 Python int 写入器实例。

实例必须通过 PyLongWriter_Finish()PyLongWriter_Discard() 销毁。

PyLongWriter *PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)

创建一个 PyLongWriter

成功时,分配 *digits 并返回一个写入器。错误时,设置异常并返回 NULL

如果数字为负,negative1,否则为 0

ndigitsdigits 数组中的位数。它必须大于 0。

digits 不能是 NULL。

成功调用此函数后,调用者应填充数字数组 digits,然后调用 PyLongWriter_Finish() 以获取一个 Python intdigits 的布局由 PyLong_GetNativeLayout() 描述。

数字必须在 [0; (1 << bits_per_digit) - 1] 范围内(其中 bits_per_digit 是每位的位数)。任何未使用的最高有效位必须设置为 0

或者,调用 PyLongWriter_Discard() 来销毁写入器实例而不创建 int 对象。

PyObject *PyLongWriter_Finish(PyLongWriter *writer)
返回值:新引用。

完成由 PyLongWriter_Create() 创建的 PyLongWriter

成功时,返回一个 Python int 对象。错误时,设置异常并返回 NULL

该函数负责对数字进行规范化,并在需要时将对象转换为紧凑整数。

调用后,写入器实例和 digits 数组无效。

void PyLongWriter_Discard(PyLongWriter *writer)

丢弃由 PyLongWriter_Create() 创建的 PyLongWriter

如果 writerNULL,则不执行任何操作。

调用后,写入器实例和 digits 数组无效。