公用对象结构体
**************

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


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

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

PyObject

   All object types are extensions of this type.  This is a type which
   contains the information Python needs to treat a pointer to an
   object as an object.  In a normal "release" build, it contains only
   the object's reference count and a pointer to the corresponding
   type object. Nothing is actually declared to be a "PyObject", but
   every pointer to a Python object can be cast to a "PyObject*".
   Access to the members must be done by using the macros "Py_REFCNT"
   and "Py_TYPE".

PyVarObject

   这是一个 "PyObject" 的添加了 "ob_size" 字段的扩展。 它仅用于具有某
   种 *长度* 标记的对象。 此类型并不经常在 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" 的文档。

Py_TYPE(o)

   This macro is used to access the "ob_type" member of a Python
   object. It expands to:

      (((PyObject*)(o))->ob_type)

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_REFCNT(o)

   This macro is used to access the "ob_refcnt" member of a Python
   object. It expands to:

      (((PyObject*)(o))->ob_refcnt)

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

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

   3.9 新版功能.

Py_SIZE(o)

   This macro is used to access the "ob_size" member of a Python
   object. It expands to:

      (((PyVarObject*)(o))->ob_size)

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,


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

PyCFunction

   Type of the functions used to implement most Python callables in C.
   Functions of this type take two "PyObject*" parameters and return
   one such value.  If the return value is "NULL", an exception shall
   have been set.  If not "NULL", the return value is interpreted as
   the return value of the function as exposed in Python.  The
   function must return a new reference.

   函数的签名为:

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

PyCFunctionWithKeywords

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

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

_PyCFunctionFast

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

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

_PyCFunctionFastWithKeywords

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

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

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 新版功能.

PyMethodDef

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

   +--------------------+-----------------+---------------------------------+
   | 域                 | C 类型          | 含意                            |
   |====================|=================|=================================|
   | "ml_name"          | const char *    | 方法名                          |
   +--------------------+-----------------+---------------------------------+
   | "ml_meth"          | PyCFunction     | 指向 C 实现的指针               |
   +--------------------+-----------------+---------------------------------+
   | "ml_flags"         | int             | flag bits indicating how the    |
   |                    |                 | call should be constructed      |
   +--------------------+-----------------+---------------------------------+
   | "ml_doc"           | const char *    | 指向文档字符串的内容            |
   +--------------------+-----------------+---------------------------------+

The "ml_meth" is a C function pointer.  The functions may be of
different types, but they always return "PyObject*".  If the function
is not of the "PyCFunction", the compiler will require a cast in the
method table. Even though "PyCFunction" defines the first parameter as
"PyObject*", it is common that the method implementation uses the
specific C type of the *self* object.

The "ml_flags" field is a bitfield which can include the following
flags. The individual flags indicate either a calling convention or a
binding convention.

调用惯例有如下这些:

METH_VARARGS

   This is the typical calling convention, where the methods have the
   type "PyCFunction". The function expects two "PyObject*" values.
   The first one is the *self* object for methods; for module
   functions, it is the module object.  The second parameter (often
   called *args*) is a tuple object representing all arguments. This
   parameter is typically processed using "PyArg_ParseTuple()" or
   "PyArg_UnpackTuple()".

METH_VARARGS | METH_KEYWORDS

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

METH_FASTCALL

   Fast calling convention supporting only positional arguments. The
   methods have the type "_PyCFunctionFast". The first parameter is
   *self*, the second parameter is a C array of "PyObject*" values
   indicating the arguments and the third parameter is the number of
   arguments (the length of the array).

   This is not part of the limited API.

   3.7 新版功能.

METH_FASTCALL | METH_KEYWORDS

   Extension of "METH_FASTCALL" supporting also keyword arguments,
   with methods of type "_PyCFunctionFastWithKeywords". Keyword
   arguments are passed the same way as in the vectorcall protocol:
   there is an additional fourth "PyObject*" parameter which is a
   tuple representing the names of the keyword arguments (which are
   guaranteed to be strings) or possibly "NULL" if there are no
   keywords.  The values of the keyword arguments are stored in the
   *args* array, after the positional arguments.

   This is not part of the limited API.

   3.7 新版功能.

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"。

METH_O

   Methods with a single object argument can be listed with the
   "METH_O" flag, instead of invoking "PyArg_ParseTuple()" with a
   ""O"" argument. They have the type "PyCFunction", with the *self*
   parameter, and a "PyObject*" parameter representing the single
   argument.

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

METH_CLASS

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

METH_STATIC

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

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

METH_COEXIST

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


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

PyMemberDef

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

   +--------------------+-----------------+---------------------------------+
   | 域                 | C 类型          | 含意                            |
   |====================|=================|=================================|
   | "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          | 长整型             |
   +-----------------+--------------------+
   | 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" 而失败时返回负值。

PyGetSetDef

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

   +---------------+--------------------+-------------------------------------+
   | 域            | C 类型             | 含意                                |
   |===============|====================|=====================================|
   | name          | const char *       | 属性名称                            |
   +---------------+--------------------+-------------------------------------+
   | get           | getter             | 用于获取属性的 C 函数               |
   +---------------+--------------------+-------------------------------------+
   | set           | setter             | 用于设置或删除属性的可选 C 函数，如 |
   |               |                    | 果省略则属性将为只读                |
   +---------------+--------------------+-------------------------------------+
   | doc           | const char *       | 可选的文档字符串                    |
   +---------------+--------------------+-------------------------------------+
   | closure       | void *             | 可选的函数指针，为 getter 和 setter |
   |               |                    | 提供附加数据                        |
   +---------------+--------------------+-------------------------------------+

   The "get" function takes one "PyObject*" parameter (the instance)
   and a function 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 function pointer (the associated
   "closure"):

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

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