abstract.rst 37.4 KB

Abstract Objects Layer

The functions in this chapter interact with Python objects regardless of their type, or with wide classes of object types (e.g. all numerical types, or all sequence types). When used on object types for which they do not apply, they will raise a Python exception.

It is not possible to use these functions on objects that are not properly initialized, such as a list object that has been created by :cfunc:`PyList_New`, but whose items have not been set to some non-NULL value yet.

Object Protocol

Subclass determination is done in a fairly straightforward way, but includes a wrinkle that implementors of extensions to the class system may want to be aware of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of :class:`A` if it inherits from :class:`A` either directly or indirectly. If either is not a class object, a more general mechanism is used to determine the class relationship of the two objects. When testing if B is a subclass of A, if A is B, :cfunc:`PyObject_IsSubclass` returns true. If A and B are different objects, B's :attr:`__bases__` attribute is searched in a depth-first fashion for A --- the presence of the :attr:`__bases__` attribute is considered sufficient for this determination.

Number Protocol

Sequence Protocol

Mapping Protocol

Iterator Protocol

There are only a couple of functions specifically for working with iterators.

To write a loop which iterates over an iterator, the C code should look something like this:

PyObject *iterator = PyObject_GetIter(obj);
PyObject *item;

if (iterator == NULL) {
    /* propagate error */
}

while (item = PyIter_Next(iterator)) {
    /* do something with item */
    ...
    /* release reference when done */
    Py_DECREF(item);
}

Py_DECREF(iterator);

if (PyErr_Occurred()) {
    /* propagate error */
}
else {
    /* continue doing useful work */
}

Buffer Protocol