对象协议¶
-
PyObject *Py_GetConstant(unsigned int constant_id)¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
获取对常量的 强引用。
如果 constant_id 无效,则设置一个异常并返回
NULL
。constant_id 必须是以下常量标识符之一
常量标识符
值
返回对象
-
Py_CONSTANT_NONE¶
0
-
Py_CONSTANT_FALSE¶
1
-
Py_CONSTANT_TRUE¶
2
-
Py_CONSTANT_ELLIPSIS¶
3
-
Py_CONSTANT_NOT_IMPLEMENTED¶
4
-
Py_CONSTANT_ZERO¶
5
0
-
Py_CONSTANT_ONE¶
6
1
-
Py_CONSTANT_EMPTY_STR¶
7
''
-
Py_CONSTANT_EMPTY_BYTES¶
8
b''
-
Py_CONSTANT_EMPTY_TUPLE¶
9
()
数值仅适用于不能使用常量标识符的项目。
在 3.13 版本加入。
CPython 实现细节: 在 CPython 中,所有这些常量都是 不朽的。
-
Py_CONSTANT_NONE¶
-
PyObject *Py_GetConstantBorrowed(unsigned int constant_id)¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
类似于
Py_GetConstant()
,但返回一个 借用引用。此函数主要用于向后兼容:对于新代码,建议使用
Py_GetConstant()
。此引用是从解释器借用的,并在解释器终止之前有效。
在 3.13 版本加入。
-
Py_RETURN_NOTIMPLEMENTED¶
正确处理从 C 函数内部返回
Py_NotImplemented
(即,创建对NotImplemented
的新 强引用 并返回它)。
-
Py_PRINT_RAW¶
用于打印对象的多个函数(如
PyObject_Print()
和PyFile_WriteObject()
)的标志。如果传入,这些函数将使用对象的str()
而不是repr()
。
-
int PyObject_Print(PyObject *o, FILE *fp, int flags)¶
将对象 o 打印到文件 fp 中。出错时返回
-1
。 flags 参数用于启用某些打印选项。当前唯一支持的选项是Py_PRINT_RAW
;如果给定,则写入对象的str()
而不是repr()
。
-
int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name)¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
如果 o 具有属性 attr_name,则返回
1
,否则返回0
。这等同于 Python 表达式hasattr(o, attr_name)
。失败时返回-1
。在 3.13 版本加入。
-
int PyObject_HasAttrStringWithError(PyObject *o, const char *attr_name)¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
这与
PyObject_HasAttrWithError()
相同,但 attr_name 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。在 3.13 版本加入。
-
int PyObject_HasAttr(PyObject *o, PyObject *attr_name)¶
- 作为 稳定 ABI 的一部分。
如果 o 具有属性 attr_name,则返回
1
,否则返回0
。此函数总是成功。备注
此函数调用
__getattr__()
和__getattribute__()
方法时发生的异常不会传播,而是交给sys.unraisablehook()
。为了进行正确的错误处理,请改用PyObject_HasAttrWithError()
、PyObject_GetOptionalAttr()
或PyObject_GetAttr()
。
-
int PyObject_HasAttrString(PyObject *o, const char *attr_name)¶
- 作为 稳定 ABI 的一部分。
这与
PyObject_HasAttr()
相同,但 attr_name 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。备注
此函数调用
__getattr__()
和__getattribute__()
方法或在创建临时str
对象时发生的异常会被静默忽略。为了进行正确的错误处理,请改用PyObject_HasAttrStringWithError()
、PyObject_GetOptionalAttrString()
或PyObject_GetAttrString()
。
-
PyObject *PyObject_GetAttr(PyObject *o, PyObject *attr_name)¶
- 返回值: 新引用。 稳定ABI 的一部分。
从对象 o 中检索名为 attr_name 的属性。成功时返回属性值,失败时返回
NULL
。这等同于 Python 表达式o.attr_name
。如果缺少属性不应被视为失败,则可以改用
PyObject_GetOptionalAttr()
。
-
PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)¶
- 返回值: 新引用。 稳定ABI 的一部分。
这与
PyObject_GetAttr()
相同,但 attr_name 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。如果缺少属性不应被视为失败,则可以改用
PyObject_GetOptionalAttrString()
。
-
int PyObject_GetOptionalAttr(PyObject *obj, PyObject *attr_name, PyObject **result);¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
PyObject_GetAttr()
的变体,如果未找到属性则不会引发AttributeError
。如果找到属性,则返回
1
并将 *result 设置为对该属性的新 强引用。如果未找到属性,则返回0
并将 *result 设置为NULL
;AttributeError
被静默。如果引发了除AttributeError
之外的错误,则返回-1
并将 *result 设置为NULL
。在 3.13 版本加入。
-
int PyObject_GetOptionalAttrString(PyObject *obj, const char *attr_name, PyObject **result);¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
这与
PyObject_GetOptionalAttr()
相同,但 attr_name 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。在 3.13 版本加入。
-
PyObject *PyObject_GenericGetAttr(PyObject *o, PyObject *name)¶
- 返回值: 新引用。 稳定ABI 的一部分。
通用属性获取函数,旨在放入类型对象的
tp_getattro
槽中。它会在对象的 MRO 中的类字典中查找描述符,以及在对象的__dict__
中查找属性(如果存在)。正如 实现描述符 中所述,数据描述符优先于实例属性,而非数据描述符则不。否则,将引发AttributeError
。
-
int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)¶
- 作为 稳定 ABI 的一部分。
将对象 o 的名为 attr_name 的属性的值设置为 v。失败时引发异常并返回
-1
;成功时返回0
。这等同于 Python 语句o.attr_name = v
。如果 v 为
NULL
,则删除该属性。此行为已弃用,建议改用PyObject_DelAttr()
,但目前没有计划将其移除。
-
int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)¶
- 作为 稳定 ABI 的一部分。
这与
PyObject_SetAttr()
相同,但 attr_name 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。如果 v 为
NULL
,则删除该属性,但此功能已弃用,建议改用PyObject_DelAttrString()
。传递给此函数的不同属性名称的数量应保持较小,通常通过使用静态分配的字符串作为 attr_name 来实现。对于在编译时未知的属性名称,请直接调用
PyUnicode_FromString()
和PyObject_SetAttr()
。有关更多详细信息,请参阅PyUnicode_InternFromString()
,它可以在内部用于创建键对象。
-
int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)¶
- 作为 稳定 ABI 的一部分。
通用属性设置器和删除器函数,旨在放入类型对象的
tp_setattro
槽中。它会在对象的 MRO 中的类字典中查找数据描述符,如果找到,它将优先于在实例字典中设置或删除属性。否则,属性将在对象的__dict__
中设置或删除(如果存在)。成功时返回0
,否则将引发AttributeError
并返回-1
。
-
int PyObject_DelAttr(PyObject *o, PyObject *attr_name)¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
删除对象 o 的名为 attr_name 的属性。失败时返回
-1
。这等同于 Python 语句del o.attr_name
。
-
int PyObject_DelAttrString(PyObject *o, const char *attr_name)¶
- 自 3.13 版本起成为 稳定 ABI 的一部分。
这与
PyObject_DelAttr()
相同,但 attr_name 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。传递给此函数的不同属性名称的数量应保持较小,通常通过使用静态分配的字符串作为 attr_name 来实现。对于在编译时未知的属性名称,请直接调用
PyUnicode_FromString()
和PyObject_DelAttr()
。有关更多详细信息,请参阅PyUnicode_InternFromString()
,它可以在内部用于创建查找的键对象。
-
PyObject **PyObject_GenericGetDict(PyObject *o, void *context)¶
- 返回值:新引用。 自 3.10 版本起成为 稳定 ABI 的一部分。
一个用于
__dict__
描述符获取器的通用实现。如有必要,它会创建字典。此函数也可以用于获取对象 o 的
__dict__
。调用时将 context 传入NULL
。由于此函数可能需要为字典分配内存,因此在访问对象的属性时调用PyObject_GetAttr()
可能会更有效。失败时,返回
NULL
并设置异常。在 3.3 版本加入。
-
int PyObject_GenericSetDict(PyObject *o, PyObject *value, void *context)¶
- 自 3.7 版本起成为 稳定ABI 的一部分。
一个用于
__dict__
描述符设置器的通用实现。此实现不允许删除字典。在 3.3 版本加入。
-
PyObject **_PyObject_GetDictPtr(PyObject *obj)¶
返回指向对象 obj 的
__dict__
的指针。如果没有__dict__
,则返回NULL
而不设置异常。此函数可能需要为字典分配内存,因此在访问对象的属性时调用
PyObject_GetAttr()
可能会更有效。
-
PyObject *PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)¶
- 返回值: 新引用。 稳定ABI 的一部分。
使用 opid 指定的操作比较 o1 和 o2 的值,opid 必须是
Py_LT
、Py_LE
、Py_EQ
、Py_NE
、Py_GT
或Py_GE
之一,分别对应<
、<=
、==
、!=
、>
或>=
。这等同于 Python 表达式o1 op o2
,其中op
是对应于 opid 的运算符。成功时返回比较结果的值,失败时返回NULL
。
-
int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)¶
- 作为 稳定 ABI 的一部分。
使用 opid 指定的操作比较 o1 和 o2 的值,类似于
PyObject_RichCompare()
,但错误时返回-1
,如果结果为假则返回0
,否则返回1
。
备注
如果 o1 和 o2 是相同的对象,则 PyObject_RichCompareBool()
对于 Py_EQ
总是返回 1
,对于 Py_NE
总是返回 0
。
-
PyObject *PyObject_Format(PyObject *obj, PyObject *format_spec)¶
- 作为 稳定 ABI 的一部分。
使用 format_spec 格式化 obj。这等同于 Python 表达式
format(obj, format_spec)
。format_spec 可以是
NULL
。在这种情况下,此调用等同于format(obj)
。成功时返回格式化字符串,失败时返回NULL
。
-
PyObject *PyObject_Repr(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
计算对象 o 的字符串表示。成功时返回字符串表示,失败时返回
NULL
。这等同于 Python 表达式repr(o)
。由内置函数repr()
调用。3.4 版本中已更改: 此函数现在包含一个调试断言,以帮助确保它不会静默丢弃活动的异常。
-
PyObject *PyObject_ASCII(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
与
PyObject_Repr()
相同,计算对象 o 的字符串表示,但使用\x
、\u
或\U
转义PyObject_Repr()
返回的字符串中的非 ASCII 字符。这会生成一个类似于 Python 2 中PyObject_Repr()
返回的字符串。由内置函数ascii()
调用。
-
PyObject *PyObject_Str(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
计算对象 o 的字符串表示。成功时返回字符串表示,失败时返回
NULL
。这等同于 Python 表达式str(o)
。由内置函数str()
调用,因此也由函数print()
调用。3.4 版本中已更改: 此函数现在包含一个调试断言,以帮助确保它不会静默丢弃活动的异常。
-
PyObject *PyObject_Bytes(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
计算对象 o 的字节表示。失败时返回
NULL
,成功时返回字节对象。这等同于 Python 表达式bytes(o)
,当 o 不是整数时。与bytes(o)
不同,当 o 是整数而不是零初始化的字节对象时,会引发 TypeError。
-
int PyObject_IsSubclass(PyObject *derived, PyObject *cls)¶
- 作为 稳定 ABI 的一部分。
如果类 derived 与类 cls 相同或派生自类 cls,则返回
1
,否则返回0
。如果出错,返回-1
。如果 cls 是一个元组,则将对 cls 中的每个条目进行检查。如果至少有一个检查返回
1
,则结果为1
,否则为0
。如果 cls 具有
__subclasscheck__()
方法,则将调用它来确定子类状态,如 PEP 3119 中所述。否则,如果 derived 是 cls 的直接或间接子类,即包含在cls.__mro__
中,则 derived 是 cls 的子类。通常只有类对象,即
type
或派生类的实例,才被视为类。然而,对象可以通过具有__bases__
属性(必须是基类元组)来覆盖此设置。
-
int PyObject_IsInstance(PyObject *inst, PyObject *cls)¶
- 作为 稳定 ABI 的一部分。
如果 inst 是类 cls 的实例或 cls 的子类,则返回
1
,否则返回0
。出错时,返回-1
并设置异常。如果 cls 是一个元组,则将对 cls 中的每个条目进行检查。如果至少有一个检查返回
1
,则结果为1
,否则为0
。如果 cls 具有
__instancecheck__()
方法,则将调用它来确定子类状态,如 PEP 3119 中所述。否则,如果 inst 的类是 cls 的子类,则 inst 是 cls 的实例。实例 inst 可以通过具有
__class__
属性来覆盖被视为其类的对象。对象 cls 可以通过具有
__bases__
属性(必须是基类元组)来覆盖其是否被视为类以及其基类是什么。
-
Py_hash_t PyObject_Hash(PyObject *o)¶
- 作为 稳定 ABI 的一部分。
计算并返回对象 o 的哈希值。失败时返回
-1
。这等同于 Python 表达式hash(o)
。3.2 版本中已更改: 返回类型现在是 Py_hash_t。这是一个带符号整数,大小与
Py_ssize_t
相同。
-
Py_hash_t PyObject_HashNotImplemented(PyObject *o)¶
- 作为 稳定 ABI 的一部分。
设置一个
TypeError
,指示type(o)
不可 哈希,并返回-1
。此函数在存储到tp_hash
槽中时会受到特殊处理,允许类型明确向解释器指示其不可哈希。
-
int PyObject_IsTrue(PyObject *o)¶
- 作为 稳定 ABI 的一部分。
如果对象 o 被认为是真的,则返回
1
,否则返回0
。这等同于 Python 表达式not not o
。失败时返回-1
。
-
int PyObject_Not(PyObject *o)¶
- 作为 稳定 ABI 的一部分。
如果对象 o 被认为是真的,则返回
0
,否则返回1
。这等同于 Python 表达式not o
。失败时返回-1
。
-
PyObject *PyObject_Type(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
当 o 非
NULL
时,返回与对象 o 的对象类型对应的类型对象。失败时,引发SystemError
并返回NULL
。这等同于 Python 表达式type(o)
。此函数创建对返回值的新的 强引用。除了需要新的 强引用 之外,实在没有理由使用此函数而不是Py_TYPE()
函数,后者返回类型为 PyTypeObject* 的指针。
-
int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)¶
如果对象 o 是 type 类型或 type 的子类型,则返回非零值,否则返回
0
。两个参数都必须是非NULL
。
-
Py_ssize_t PyObject_Size(PyObject *o)¶
-
Py_ssize_t PyObject_Length(PyObject *o)¶
- 作为 稳定 ABI 的一部分。
返回对象 o 的长度。如果对象 o 提供序列和映射协议,则返回序列长度。错误时返回
-1
。这等同于 Python 表达式len(o)
。
-
Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)¶
返回对象 o 的估计长度。首先尝试返回其实际长度,然后使用
__length_hint__()
进行估计,最后返回默认值。错误时返回-1
。这等同于 Python 表达式operator.length_hint(o, defaultvalue)
。在 3.4 版本加入。
-
PyObject *PyObject_GetItem(PyObject *o, PyObject *key)¶
- 返回值: 新引用。 稳定ABI 的一部分。
返回 o 中与对象 key 对应的元素,失败时返回
NULL
。这等同于 Python 表达式o[key]
。
-
int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)¶
- 作为 稳定 ABI 的一部分。
将对象 key 映射到值 v。失败时引发异常并返回
-1
;成功时返回0
。这等同于 Python 语句o[key] = v
。此函数 不会 窃取对 v 的引用。
-
int PyObject_DelItem(PyObject *o, PyObject *key)¶
- 作为 稳定 ABI 的一部分。
从对象 o 中移除对象 key 的映射。失败时返回
-1
。这等同于 Python 语句del o[key]
。
-
int PyObject_DelItemString(PyObject *o, const char *key)¶
- 作为 稳定 ABI 的一部分。
这与
PyObject_DelItem()
相同,但 key 被指定为 const char* UTF-8 编码字节字符串,而不是 PyObject*。
-
PyObject *PyObject_Dir(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
这等同于 Python 表达式
dir(o)
,返回一个(可能为空的)适合对象参数的字符串列表,或者在出错时返回NULL
。如果参数为NULL
,则类似于 Python 的dir()
,返回当前局部变量的名称;在这种情况下,如果没有活动的执行帧,则返回NULL
,但PyErr_Occurred()
将返回 false。
-
PyObject *PyObject_GetIter(PyObject *o)¶
- 返回值: 新引用。 稳定ABI 的一部分。
这等同于 Python 表达式
iter(o)
。它为对象参数返回一个新的迭代器,如果对象本身已经是迭代器,则返回对象本身。如果对象不可迭代,则引发TypeError
并返回NULL
。
-
PyObject *PyObject_SelfIter(PyObject *obj)¶
- 返回值: 新引用。 稳定ABI 的一部分。
这等同于 Python 的
__iter__(self): return self
方法。它旨在用于 迭代器 类型,用于PyTypeObject.tp_iter
槽。
-
PyObject *PyObject_GetAIter(PyObject *o)¶
- 返回值:新引用。 自 3.10 版本起成为 稳定 ABI 的一部分。
这等同于 Python 表达式
aiter(o)
。它接受一个AsyncIterable
对象,并返回其AsyncIterator
。这通常是一个新的迭代器,但如果参数是一个AsyncIterator
,则返回自身。如果对象不可迭代,则引发TypeError
并返回NULL
。在 3.10 版本加入。
-
void *PyObject_GetTypeData(PyObject *o, PyTypeObject *cls)¶
- 自 3.12 版本起成为 稳定 ABI 的一部分。
获取指向为 cls 保留的子类特定数据的指针。
对象 o 必须是 cls 的实例,并且 cls 必须使用负的
PyType_Spec.basicsize
创建。Python 不会检查这一点。出错时,设置异常并返回
NULL
。3.12 新版功能.
-
Py_ssize_t PyType_GetTypeDataSize(PyTypeObject *cls)¶
- 自 3.12 版本起成为 稳定 ABI 的一部分。
返回为 cls 保留的实例内存空间的大小,即
PyObject_GetTypeData()
返回的内存大小。这可能大于使用负的
PyType_Spec.basicsize
请求的大小;使用此更大的大小(例如与memset()
)是安全的。类型 cls 必须 使用负的
PyType_Spec.basicsize
创建。Python 不会检查这一点。出错时,设置异常并返回负值。
3.12 新版功能.
-
void *PyObject_GetItemData(PyObject *o)¶
获取指向具有
Py_TPFLAGS_ITEMS_AT_END
的类的每项数据的指针。出错时,设置异常并返回
NULL
。如果 o 未设置Py_TPFLAGS_ITEMS_AT_END
,则会引发TypeError
。3.12 新版功能.
-
int PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg)¶
访问 obj 的托管字典。
此函数只能在具有
Py_TPFLAGS_MANAGED_DICT
标志的类型遍历函数中调用。在 3.13 版本加入。
-
void PyObject_ClearManagedDict(PyObject *obj)¶
清除 obj 的托管字典。
此函数只能在具有
Py_TPFLAGS_MANAGED_DICT
标志的类型清除函数中调用。在 3.13 版本加入。
-
int PyUnstable_Object_EnableDeferredRefcount(PyObject *obj)¶
- 这是一个 不稳定 API。它可能会在次要版本中未经警告而更改。
如果运行时支持,则在 obj 上启用 延迟引用计数。在 自由线程 构建中,这允许解释器避免对 obj 的引用计数调整,这可能会提高多线程性能。权衡是 obj 将仅由跟踪垃圾回收器解除分配,而不是在解释器不再对其有任何引用时解除分配。
如果 obj 上启用了延迟引用计数,则此函数返回
1
;如果不支持延迟引用计数,或者解释器忽略了此提示(例如 obj 上已启用延迟引用计数),则返回0
。此函数是线程安全的,并且不会失败。在启用了 GIL 的构建中,此函数不执行任何操作,这些构建不支持延迟引用计数。如果 obj 不是垃圾回收器跟踪的对象(参见
gc.is_tracked()
和PyObject_GC_IsTracked()
),此函数也不执行任何操作。此函数旨在在 obj 创建后不久,由创建它的代码使用,例如在对象的
tp_new
槽中。在 3.14 版本加入。
-
int PyUnstable_Object_IsUniqueReferencedTemporary(PyObject *obj)¶
- 这是一个 不稳定 API。它可能会在次要版本中未经警告而更改。
检查 obj 是否是唯一的临时对象。如果 obj 已知是唯一的临时对象,则返回
1
,否则返回0
。此函数不会失败,但检查是保守的,即使 obj 是唯一的临时对象,在某些情况下也可能返回0
。如果一个对象是唯一的临时对象,则保证当前代码是唯一引用该对象的。对于 C 函数的参数,应使用此方法而不是检查引用计数是否为
1
。从 Python 3.14 开始,解释器通过在可能时 借用 引用,内部避免在将对象加载到操作数堆栈时进行一些引用计数修改,这意味着引用计数为1
本身并不能保证函数参数是唯一引用的。在下面的示例中,
my_func
被调用,其参数是唯一的临时对象。my_func([1, 2, 3])
在下面的示例中,
my_func
没有被调用,其参数是唯一的临时对象,即使其引用计数为1
。my_list = [1, 2, 3] my_func(my_list)
另请参阅函数
Py_REFCNT()
。在 3.14 版本加入。
-
int PyUnstable_IsImmortal(PyObject *obj)¶
- 这是一个 不稳定 API。它可能会在次要版本中未经警告而更改。
如果 obj 是 不朽的,此函数返回非零值,否则返回零。此函数不会失败。
备注
在一个 CPython 版本中不朽的对象不能保证在另一个版本中也是不朽的。
在 3.14 版本加入。
-
int PyUnstable_TryIncRef(PyObject *obj)¶
- 这是一个 不稳定 API。它可能会在次要版本中未经警告而更改。
如果 obj 的引用计数不为零,则将其引用计数加一。如果对象引用计数成功递增,则返回
1
。否则,此函数返回0
。必须在此函数之前在 obj 上调用过
PyUnstable_EnableTryIncRef()
,否则此函数在 自由线程 构建中可能会错误地返回0
。此函数在逻辑上等同于以下 C 代码,但在 自由线程 构建中它会原子地执行
if (Py_REFCNT(op) > 0) { Py_INCREF(op); return 1; } return 0;
这旨在作为管理弱引用而不产生 Python 弱引用对象 开销的构建块。
通常,正确使用此函数需要 obj 的解除分配器 (
tp_dealloc
) 的支持。例如,以下草图可以适用于实现一个“弱映射”,其作用类似于特定类型的WeakValueDictionary
PyMutex mutex; PyObject * add_entry(weakmap_key_type *key, PyObject *value) { PyUnstable_EnableTryIncRef(value); weakmap_type weakmap = ...; PyMutex_Lock(&mutex); weakmap_add_entry(weakmap, key, value); PyMutex_Unlock(&mutex); Py_RETURN_NONE; } PyObject * get_value(weakmap_key_type *key) { weakmap_type weakmap = ...; PyMutex_Lock(&mutex); PyObject *result = weakmap_find(weakmap, key); if (PyUnstable_TryIncRef(result)) { // `result` is safe to use PyMutex_Unlock(&mutex); return result; } // if we get here, `result` is starting to be garbage-collected, // but has not been removed from the weakmap yet PyMutex_Unlock(&mutex); return NULL; } // tp_dealloc function for weakmap values void value_dealloc(PyObject *value) { weakmap_type weakmap = ...; PyMutex_Lock(&mutex); weakmap_remove_value(weakmap, value); ... PyMutex_Unlock(&mutex); }
在 3.14 版本加入。
-
void PyUnstable_EnableTryIncRef(PyObject *obj)¶
- 这是一个 不稳定 API。它可能会在次要版本中未经警告而更改。
在 obj 上启用后续的
PyUnstable_TryIncRef()
调用。调用此函数时,调用者必须持有对 obj 的 强引用。在 3.14 版本加入。
-
int PyUnstable_Object_IsUniquelyReferenced(PyObject *op)¶
- 这是一个 不稳定 API。它可能会在次要版本中未经警告而更改。
确定 op 是否只有一份引用。
在启用 GIL 的构建中,此函数等同于 Py_REFCNT(op) == 1。
在 自由线程 构建中,此函数检查 op 的 引用计数 是否等于一,并额外检查 op 是否仅被当前线程使用。在自由线程构建中,Py_REFCNT(op) == 1 不是线程安全的;优先使用此函数。
调用者必须持有 附加线程状态,尽管此函数不会调用 Python 解释器。此函数不会失败。
在 3.14 版本加入。