通用物件結構
************

大量的结构体被用于定义Python的对象类型。这一节描述了这些的结构体和它们
的使用方法。


基本的对象类型和宏
==================

所有的 Python 对象都在对象的内存表示的开始部分共享少量的字段。 这些字
段用 "PyObject" 或 "PyVarObject" 类型来表示，这些类型又由一些宏定义，
这些宏也直接或间接地用于所有其他 Python 对象的定义。

type PyObject
    * 属于 受限 API. （仅特定成员属于稳定 ABI。）*

   所有对象类型都是此类型的扩展。 这是一个包含了 Python 将对象的指针当
   作对象来处理所需的信息的类型。 在一个普通的“发行”编译版中，它只包含
   对象的引用计数和指向对应类型对象的指针。 没有什么对象被实际声明为
   "PyObject"，但每个指向 Python 对象的指针都可以被转换为 PyObject*。
   对成员的访问必须通过使用 "Py_REFCNT" 和 "Py_TYPE" 宏来完成。

type PyVarObject
    * 属于 受限 API. （仅特定成员属于稳定 ABI。）*

   这是一个添加了 "ob_size" 字段的 "PyObject" 扩展。 它仅用于具有某些
   *长度* 标记的对象。 此类型并不经常在 Python/C API 中出现。 对成员的
   访问必须通过使用 "Py_REFCNT", "Py_TYPE" 和 "Py_SIZE" 宏来完成。

PyObject_HEAD

   这是一个在声明代表无可变长度对象的新类型时所使用的宏。
   PyObject_HEAD 宏被扩展为:

      PyObject ob_base;

   参见上面 "PyObject" 的文档。

PyObject_VAR_HEAD

   这是一个在声明代表每个实例具有可变长度的对象时所使用的宏。
   PyObject_VAR_HEAD 宏被扩展为:

      PyVarObject ob_base;

   参见上面 "PyVarObject" 的文档。

int Py_Is(PyObject *x, PyObject *y)
    * 属于 稳定 ABI 自 3.10 版起.*

   测试 *x* 是否为 *y* 对象，与 Python 中的 "x is y" 相同。

   在 3.10 版新加入.

int Py_IsNone(PyObject *x)
    * 属于 稳定 ABI 自 3.10 版起.*

   测试一个对象是否为 "None" 单例，与 Python 中的 "x is None" 相同。

   在 3.10 版新加入.

int Py_IsTrue(PyObject *x)
    * 属于 稳定 ABI 自 3.10 版起.*

   测试一个对象是否为 "True" 单例，与 Python 中的 "x is True" 相同。

   在 3.10 版新加入.

int Py_IsFalse(PyObject *x)
    * 属于 稳定 ABI 自 3.10 版起.*

   测试一个对象是否为 "False" 单例，与 Python 中的 "x is False" 相同。

   在 3.10 版新加入.

PyTypeObject *Py_TYPE(PyObject *o)

   获取 Python 对象 *o* 的类型。

   返回一个 *borrowed reference*。

   使用 "Py_SET_TYPE()" 函数来设置一个对象类型。

   在 3.11 版的變更: "Py_TYPE()" 被改为一个内联的静态函数。 形参类型不
   再是 const PyObject*。

int Py_IS_TYPE(PyObject *o, PyTypeObject *type)

   如果对象 *o* 的类型为 *type* 则返回非零值。 否则返回零。 等价于:
   "Py_TYPE(o) == type"。

   在 3.9 版新加入.

void Py_SET_TYPE(PyObject *o, PyTypeObject *type)

   将对象 *o* 的类型设为 *type*。

   在 3.9 版新加入.

Py_ssize_t Py_REFCNT(PyObject *o)

   获取 Python 对象 *o* 的引用计数。

   使用 "Py_SET_REFCNT()" 函数来设置一个对象引用计数。

   在 3.11 版的變更: 形参类型不再是 const PyObject*。

   在 3.10 版的變更: "Py_REFCNT()" 被改为内联的静态函数。

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

   将对象 *o* 的引用计数器设为 *refcnt*。

   在 3.9 版新加入.

Py_ssize_t Py_SIZE(PyVarObject *o)

   获取 Python 对象 *o* 的大小。

   使用 "Py_SET_SIZE()" 函数来设置一个对象大小。

   在 3.11 版的變更: "Py_SIZE()" 被改为一个内联静态函数。 形参类型不再
   是 const PyVarObject*。

void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)

   将对象 *o* 的大小设为 *size*。

   在 3.9 版新加入.

PyObject_HEAD_INIT(type)

   这是一个为新的 "PyObject" 类型扩展初始化值的宏。 该宏扩展为:

      _PyObject_EXTRA_INIT
      1, type,

PyVarObject_HEAD_INIT(type, size)

   这是一个为新的 "PyVarObject" 类型扩展初始化值的宏，包括 "ob_size"
   字段。 该宏会扩展为:

      _PyObject_EXTRA_INIT
      1, type, size,


实现函数和方法
==============

type PyCFunction
    * 属于 稳定 ABI.*

   用于在 C 中实现大多数 Python 可调用对象的函数类型。 该类型的函数接
   受两个 PyObject* 形参并返回一个这样的值。 如果返回值为 "NULL"，则将
   设置一个异常。 如果不为 "NULL"，则返回值将被解读为 Python 中暴露的
   函数的返回值。 此函数必须返回一个新的引用。

   函数的签名为:

      PyObject *PyCFunction(PyObject *self,
                            PyObject *args);

type PyCFunctionWithKeywords
    * 属于 稳定 ABI.*

   用于在 C 中实现具有 METH_VARARGS | METH_KEYWORDS 签名的 Python 可调
   用对象的函数类型。 函数的签名为:

      PyObject *PyCFunctionWithKeywords(PyObject *self,
                                        PyObject *args,
                                        PyObject *kwargs);

type _PyCFunctionFast

   用于在 C 中实现具有 "METH_FASTCALL" 签名的 Python 可调用对象的函数
   类型。 函数的签名为:

      PyObject *_PyCFunctionFast(PyObject *self,
                                 PyObject *const *args,
                                 Py_ssize_t nargs);

type _PyCFunctionFastWithKeywords

   用于在 C 中实现具有 METH_FASTCALL | METH_KEYWORDS 签名的 Python 可
   调用对象的函数类型。 函数的签名为:

      PyObject *_PyCFunctionFastWithKeywords(PyObject *self,
                                             PyObject *const *args,
                                             Py_ssize_t nargs,
                                             PyObject *kwnames);

type PyCMethod

   用于在 C 中实现具有 METH_METHOD | METH_FASTCALL | METH_KEYWORDS 签
   名的 Python 可调用对象的函数类型。 函数的签名为:

      PyObject *PyCMethod(PyObject *self,
                          PyTypeObject *defining_class,
                          PyObject *const *args,
                          Py_ssize_t nargs,
                          PyObject *kwnames)

   在 3.9 版新加入.

type PyMethodDef
    * 属于 稳定 ABI （包括所有成员）.*

   用于描述一个扩展类型的方法的结构体。 该结构体有四个字段:

   const char *ml_name

      方法的名称。

   PyCFunction ml_meth

      指向 C 语言实现的指针。

   int ml_flags

      指明调用应当如何构建的旗标位。

   const char *ml_doc

      指向文档字符串的内容。

"ml_meth" 是一个 C 函数指针。 该函数可以为不同类型，但它们将总是返回
PyObject*。 如果该函数不属于 "PyCFunction"，则编译器将要求在方法表中进
行转换。 尽管 "PyCFunction" 将第一个参数定义为 PyObject*，但该方法的实
现使用 *self* 对象的特定 C 类型也很常见。

"ml_flags" 字段是可以包含以下旗标的位字段。 每个旗标表示一个调用惯例或
绑定惯例。

调用惯例有如下这些:

METH_VARARGS

   这是典型的调用惯例，其中方法的类型为 "PyCFunction"。 该函数接受两个
   PyObject* 值。 第一个是用于方法的 *self* 对象；对于模块函数，它将为
   模块对象。 第二个形参 (常被命名为 *args*) 是一个代表所有参数的元组
   对象。 该形参通常是使用 "PyArg_ParseTuple()" 或
   "PyArg_UnpackTuple()" 来处理的。

METH_KEYWORDS

   只能用于同其他旗标形成特定的组合: METH_VARARGS | METH_KEYWORDS,
   METH_FASTCALL | METH_KEYWORDS 和 METH_METHOD | METH_FASTCALL |
   METH_KEYWORDS。

METH_VARARGS | METH_KEYWORDS
   带有这些旗标的方法必须为 "PyCFunctionWithKeywords" 类型。 该函数接
   受三个形参: *self*, *args*, *kwargs* 其中 *kwargs* 是一个包含所有关
   键字参数的字典或者如果没有关键字参数则可以为 "NULL"。 这些形参通常
   是使用 "PyArg_ParseTupleAndKeywords()" 来处理的。

METH_FASTCALL

   快速调用惯例仅支持位置参数。 这些方法的类型为 "_PyCFunctionFast"。
   第一个形参为 *self*，第二个形参是由表示参数的 PyObject* 值组成的数
   组而第三个形参是参数的数量（数组的长度）。

   在 3.7 版新加入.

   在 3.10 版的變更: "METH_FASTCALL" 现在是 稳定 ABI 的一部分。

METH_FASTCALL | METH_KEYWORDS
   "METH_FASTCALL" 的扩展也支持关键字参数，它使用类型为
   "_PyCFunctionFastWithKeywords" 的方法。 关键字参数的传递方式与
   vectorcall 协议 中的相同：还存在额外的第四个 PyObject* 参数，它是一
   个代表关键字参数名称（它将保证为字符串）的元组，或者如果没有关键字
   则可以为 "NULL"。 关键字参数的值存放在 *args* 数组中，在位置参数之
   后。

   在 3.7 版新加入.

METH_METHOD

   只能与其他旗标组合使用: METH_METHOD | METH_FASTCALL | METH_KEYWORDS
   。

METH_METHOD | METH_FASTCALL | METH_KEYWORDS
   METH_FASTCALL | METH_KEYWORDS 的扩展支持 *定义式类*，也就是包含相应
   方法的类。 定义式类可以是 "Py_TYPE(self)" 的超类。

   该方法必须为 "PyCMethod" 类型，与在 "self" 之后添加了
   "defining_class" 参数的 "METH_FASTCALL | METH_KEYWORDS" 一样。

   在 3.9 版新加入.

METH_NOARGS

   如果通过 "METH_NOARGS" 旗标列出了参数则没有形参的方法无需检查是否给
   出了参数。 它们必须为 "PyCFunction" 类型。 第一个形参通常被命名为
   *self* 并将持有对模块或对象实例的引用。 在所有情况下第二个形参都将
   为 "NULL"。

   该函数必须有 2 个形参。 由于第二个形参不会被使用，"Py_UNUSED" 可以
   被用来防止编译器警告。

METH_O

   具有一个单独对象参数的方法可使用 "METH_O" 旗标列出，而不必唤起
   "PyArg_ParseTuple()" 并附带 ""O"" 参数。 它们的类型为 "PyCFunction"
   ，带有 *self* 形参，以及代表该单独参数的 PyObject* 形参。

这两个常量不是被用来指明调用惯例而是在配合类方法使用时指明绑定。 它们
不会被用于在模块上定义的函数。 对于任何给定方法这些旗标最多只会设置其
中一个。

METH_CLASS

   该方法将接受类型对象而不是类型的实例作为第一个形参。 它会被用于创建
   *类方法*，类似于使用 "classmethod()" 内置函数所创建的结果。

METH_STATIC

   该方法将接受 "NULL" 而不是类型的实例作为第一个形参。 它会被用于创建
   *静态方法*，类似于使用 "staticmethod()" 内置函数所创建的结果。

另一个常量控制方法是否将被载入来替代具有相同方法名的另一个定义。

METH_COEXIST

   该方法将被加载以替代现有的定义。 如果没有 *METH_COEXIST*，默认将跳
   过重复的定义。 由于槽位包装器会在方法表之前被加载，例如 当存在
   *sq_contains* 槽位时，将会生成一个名为 "__contains__()" 的已包装方
   法并阻止加载同名的相应 PyCFunction。 如果定义了此旗标，PyCFunction
   将被加载以替代此包装器对象并与槽位共存。 因为对 PyCFunction 的调用
   相比对包装器对象调用更为优化所以这是很有帮助的。

PyObject *PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *cls)
    *回傳值：新的參照。** 属于 稳定 ABI 自 3.9 版起.*

   将 *ml* 转为一个 Python *callable* 对象。 调用方必须确保 *ml* 的生
   命期长于 *callable*。 通常，*ml* 会被定义为一个静态变量。

   *self* 形参将在唤起时作为 "ml->ml_meth" 中 C 函数的 *self* 参数传入
   。 *self* 可以为 "NULL"。

   *callable* 对象的 "__module__" 属性可以根据给定的 *module* 参数来设
   置。 *module* 应为一个 Python 字符串，它将被用作函数定义所在的模块
   名称。 如果不可用，它将被设为 "None" 或 "NULL"。

   也參考: "function.__module__"

   *cls* 形参将被作为 C 函数的 *defining_class* 参数传入。 如果在
   "ml->ml_flags" 上设置了 "METH_METHOD" 则必须设置该形参。

   在 3.9 版新加入.

PyObject *PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
    *回傳值：新的參照。** 属于 稳定 ABI.*

   等价于 "PyCMethod_New(ml, self, module, NULL)"。

PyObject *PyCFunction_New(PyMethodDef *ml, PyObject *self)
    *回傳值：新的參照。** 属于 稳定 ABI 自 3.4 版起.*

   等价于 "PyCMethod_New(ml, self, NULL, NULL)"。


访问扩展类型的属性
==================

type PyMemberDef
    * 属于 稳定 ABI （包括所有成员）.*

   描述与某个 C 结构体成员相对应的类型的属性的结构体。 它的字段有:

   +--------------------+-----------------+---------------------------------+
   | 域                 | C Type          | 含意                            |
   |====================|=================|=================================|
   | "name"             | const char *    | 成员名称                        |
   +--------------------+-----------------+---------------------------------+
   | "type"             | int             | C 结构体中成员的类型            |
   +--------------------+-----------------+---------------------------------+
   | "offset"           | Py_ssize_t      | 成员在类型的对象结构体中所在位  |
   |                    |                 | 置的以字节表示的偏移量          |
   +--------------------+-----------------+---------------------------------+
   | "flags"            | int             | 指明字段是否应为只读或可写的旗  |
   |                    |                 | 标位                            |
   +--------------------+-----------------+---------------------------------+
   | "doc"              | const char *    | 指向文档字符串的内容            |
   +--------------------+-----------------+---------------------------------+

   "type" 可以是与各种 C 类型相对应的许多 "T_" 宏中的一个。 当在
   Python 中访问该成员时，它将被转换为等价的 Python 类型。

   +-----------------+--------------------+
   | 宏名称          | C 类型             |
   |=================|====================|
   | T_SHORT         | short              |
   +-----------------+--------------------+
   | T_INT           | int                |
   +-----------------+--------------------+
   | T_LONG          | long               |
   +-----------------+--------------------+
   | T_FLOAT         | float              |
   +-----------------+--------------------+
   | T_DOUBLE        | double             |
   +-----------------+--------------------+
   | T_STRING        | const char *       |
   +-----------------+--------------------+
   | T_OBJECT        | PyObject *         |
   +-----------------+--------------------+
   | T_OBJECT_EX     | PyObject *         |
   +-----------------+--------------------+
   | T_CHAR          | char               |
   +-----------------+--------------------+
   | T_BYTE          | char               |
   +-----------------+--------------------+
   | T_UBYTE         | unsigned char      |
   +-----------------+--------------------+
   | T_UINT          | unsigned int       |
   +-----------------+--------------------+
   | T_USHORT        | unsigned short     |
   +-----------------+--------------------+
   | T_ULONG         | unsigned long      |
   +-----------------+--------------------+
   | T_BOOL          | char               |
   +-----------------+--------------------+
   | T_LONGLONG      | long long          |
   +-----------------+--------------------+
   | T_ULONGLONG     | unsigned long long |
   +-----------------+--------------------+
   | T_PYSSIZET      | Py_ssize_t         |
   +-----------------+--------------------+

   "T_OBJECT" 和 "T_OBJECT_EX" 的区别在于 "T_OBJECT" 返回 "None" 表示
   其成员为 "NULL" 并且 "T_OBJECT_EX" 引发了 "AttributeError"。 请尝试
   使用 "T_OBJECT_EX" 取代 "T_OBJECT" 因为 "T_OBJECT_EX" 处理在属性上
   使用 "del" 语句比 "T_OBJECT" 更正确。

   "flags" 可以为 "0" 表示读写访问或 "READONLY" 表示只读访问。 使用
   "T_STRING" 作为 "type" 表示 "READONLY"。 "T_STRING" 数据将被解读为
   UTF-8 编码格式。 只有 "T_OBJECT" 和 "T_OBJECT_EX" 成员可以被删除。
   (它们会被设为 "NULL")。

   堆分配类型 (使用 "PyType_FromSpec()" 或类似函数创建), "PyMemberDef"
   可以包含特殊成员 "__dictoffset__", "__weaklistoffset__" 和
   "__vectorcalloffset__" 的定义，对应类型对象中的 "tp_dictoffset",
   "tp_weaklistoffset" 和 "tp_vectorcall_offset"。 它们必须使用
   "T_PYSSIZET" 和 "READONLY" 来定义，例如:

      static PyMemberDef spam_type_members[] = {
          {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY},
          {NULL}  /* Sentinel */
      };

PyObject *PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m)

   获取属于地址Get an attribute belonging to the object at address
   *obj_addr* 上的对象的某个属性。 该属性是以 "PyMemberDef" *m* 来描述
   的。 出错时返回 "NULL"。

int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o)

   将属于位于地址 *obj_addr* 的对象的属性设置到对象 *o*。 要设置的属性
   由 "PyMemberDef" *m* 描述。 成功时返回 "0" 而失败时返回负值。

type PyGetSetDef
    * 属于 稳定 ABI （包括所有成员）.*

   用于定义针对某个类型的特征属性式的访问的结构体。 另请参阅
   "PyTypeObject.tp_getset" 槽位的描述。

   +---------------+--------------------+-------------------------------------+
   | 域            | C Type             | 含意                                |
   |===============|====================|=====================================|
   | name          | const char *       | 属性名称                            |
   +---------------+--------------------+-------------------------------------+
   | get           | getter             | 用于获取属性的 C 函数               |
   +---------------+--------------------+-------------------------------------+
   | set           | setter             | 用于设置或删除属性的可选 C 函数，如 |
   |               |                    | 果省略则属性将为只读                |
   +---------------+--------------------+-------------------------------------+
   | doc           | const char *       | 可选的文档字符串                    |
   +---------------+--------------------+-------------------------------------+
   | closure       | void *             | optional user data pointer,         |
   |               |                    | providing additional data for       |
   |               |                    | getter and setter                   |
   +---------------+--------------------+-------------------------------------+

   The "get" function takes one PyObject* parameter (the instance) and
   a user data pointer (the associated "closure"):

      typedef PyObject *(*getter)(PyObject *, void *);

   它应当在成功时返回一个新的引用或在失败时返回 "NULL" 并设置异常。

   "set" functions take two PyObject* parameters (the instance and the
   value to be set) and a user data pointer (the associated
   "closure"):

      typedef int (*setter)(PyObject *, PyObject *, void *);

   对于属性要被删除的情况第二个形参应为 "NULL"。 成功时应返回 "0" 或在
   失败时返回 "-1" 并设置异常。
