Типы Python и C-структуры
В коде C определено несколько новых типов. Большинство из них доступны из Python, но некоторые не экспонируются из-за ограниченного использования. Каждый новый тип Python связан с PyObject * и имеет внутреннюю структуру, которая включает указатель на «таблицу методов», определяющую поведение нового объекта в Python. При получении объекта Python в код C вы всегда получаете указатель на структуру PyObject. Поскольку структура PyObject очень общая и определяет только PyObject_HEAD, сама по себе она не очень интересна. Однако разные объекты содержат больше деталей после PyObject_HEAD (но вам нужно выполнить приведение к нужному типу, чтобы получить к ним доступ — или использовать функции-аксессоры или макросы).
Определённые новые типы Python
Типы Python — это функциональный эквивалент классов в Python в C. Создавая новый тип Python, вы делаете доступным новый объект для Python. Объект ndarray является примером нового типа, определённого в C. Новые типы определяются в C двумя основными шагами:
- создание C-структуры (обычно с именем
Py{Name}Object), которая бинарно совместима со структуройPyObject, но содержит дополнительную информацию, необходимую для этого конкретного объекта; - заполнение таблицы
PyTypeObject(на которую указывает член ob_type структурыPyObject) указателями на функции, которые реализуют желаемое поведение для типа.
Вместо специальных имён методов, которые определяют поведение для классов Python, существуют «таблицы функций», которые указывают на функции, которые реализуют желаемые результаты. Начиная с Python 2.2, сам PyTypeObject стал динамическим, что позволяет типам C, которые могут быть «подтипами» других типов C в C и подклассами в Python. Дочерние типы наследуют атрибуты и методы от своих родительских типов.
Существует два основных новых типа: ndarray ( PyArray_Type ) и ufunc ( PyUFunc_Type ). Дополнительные типы играют вспомогательную роль: PyArrayIter_Type, PyArrayMultiIter_Type, и PyArrayDescr_Type. PyArrayIter_Type — это тип плоского итератора для ndarray (объект, который возвращается при получении атрибута flat). PyArrayMultiIter_Type — это тип объекта, возвращаемого при вызове broadcast (). Он обрабатывает итерацию и трансляцию по набору вложенных последовательностей. Также PyArrayDescr_Type — это тип описателя типа данных, экземпляры которого описывают данные. Наконец, есть 21 новый скалярный тип массива, которые являются новыми скалярами Python, соответствующими каждому из основных типов данных, доступных для массивов. Ещё 10 типов являются заглушками, которые позволяют скалярам массива вписаться в иерархию реальных типов Python.
Тип PyArray_Type
-
PyArrayObject -
C-структура
PyArrayObjectсодержит всю необходимую информацию для массива. Все экземпляры ndarray (и его подклассов) будут иметь эту структуру. Для обеспечения будущей совместимости члены этой структуры обычно должны вызываться с помощью предоставленных макросов. Если вам нужно более короткое имя, вы можете использоватьNPY_AO, которое определено как эквивалентноеPyArrayObject.typedef struct PyArrayObject { PyObject_HEAD char *data; int nd; npy_intp *dimensions; npy_intp *strides; PyObject *base; PyArray_Descr *descr; int flags; PyObject *weakreflist; } PyArrayObject;
-
char *PyArrayObject.data -
Указатель на первый элемент массива. Этот указатель можно (и обычно следует) привести к типу данных массива.
-
int PyArrayObject.nd -
Целое число, определяющее количество измерений для этого массива. Когда nd равно 0, массив иногда называют массивом ранга 0. Такие массивы имеют неопределённые размеры и шаги и недоступны.
NPY_MAXDIMS— это максимальное количество измерений для любого массива.
-
npy_intp PyArrayObject.dimensions -
Массив целых чисел, предоставляющий форму в каждом измерении, пока nd
1. Целое число всегда достаточно велико, чтобы содержать указатель на платформе, поэтому размер измерения ограничен только памятью.
-
npy_intp *PyArrayObject.strides -
Массив целых чисел, предоставляющий для каждого измерения количество байт, которое необходимо пропустить, чтобы перейти к следующему элементу в этом измерении.
-
PyObject *PyArrayObject.base -
Этот член используется для хранения указателя на другой объект Python, связанный с этим массивом. Существует два случая использования: 1) Если этот массив не владеет своей собственной памятью, то base указывает на объект Python, который им владеет (возможно, другой объект массива), 2) Если для этого массива установлен флаг
NPY_ARRAY_UPDATEIFCOPY, то этот массив является рабочей копией «неправильного» массива. Как только этот массив будет удалён, массив, на который указывает base, будет обновлён содержимым этого массива.
-
PyArray_Descr *PyArrayObject.descr -
Указатель на объект-описатель типа данных (см. ниже). Объект-описатель типа данных — это экземпляр нового встроенного типа, который позволяет генерически описывать память. Существует структура описателя для каждого поддерживаемого типа данных. Эта структура описателя содержит полезную информацию о типе, а также указатель на таблицу указателей на функции для реализации конкретной функциональности.
-
int PyArrayObject.flags -
Флаги, указывающие, как интерпретировать память, на которую указывает data. Возможные флаги —
NPY_ARRAY_C_CONTIGUOUS,NPY_ARRAY_F_CONTIGUOUS,NPY_ARRAY_OWNDATA,NPY_ARRAY_ALIGNED,NPY_ARRAY_WRITEABLEиNPY_ARRAY_UPDATEIFCOPY.
-
PyObject *PyArrayObject.weakreflist -
Этот член позволяет объектам массивов иметь слабые ссылки (используя модуль weakref).
Тип PyArrayDescr_Type
-
PyArray_Descr -
Формат структуры
PyArray_Descr, лежащей в основеPyArrayDescr_Type, таков:typedef struct { PyObject_HEAD PyTypeObject *typeobj; char kind; char type; char byteorder; char unused; int flags; int type_num; int elsize; int alignment; PyArray_ArrayDescr *subarray; PyObject *fields; PyArray_ArrFuncs *f; } PyArray_Descr;
-
PyTypeObject *PyArray_Descr.typeobj -
Указатель на typeobject, который является соответствующим типом Python для элементов этого массива. Для встроенных типов он указывает на соответствующий скаляр массива. Для типов, определённых пользователем, он должен указывать на объект typeobject, определённый пользователем. Этот объект typeobject может либо наследоваться от скаляров массива, либо нет. Если он не наследуется от скаляров массива, то флаги
NPY_USE_GETITEMиNPY_USE_SETITEMдолжны быть установлены в членеflags.
-
char PyArray_Descr.kind -
Символьный код, указывающий тип массива (используя обозначение строчных типов интерфейса массива). ‘b’ — булево, ‘i’ — целое со знаком, ‘u’ — целое без знака, ‘f’ — с плавающей точкой, ‘c’ — комплексное с плавающей точкой, ‘S’ — строка символов размером 8 бит, ‘U’ — строка символов Юникода размером 32 бита, а ‘V’ — произвольный.
-
char PyArray_Descr.type -
Традиционный символьный код, указывающий тип данных.
-
char PyArray_Descr.byteorder -
Символ, указывающий порядок байтов: ‘>’ (big-endian), ‘<’ (little-endian), ‘=’ (родной), ‘|’ (нерелевантный, игнорировать). У всех встроенных типов данных порядок байтов равен ‘=’.
-
int PyArray_Descr.flags -
Флаг типа данных, определяющий, демонстрирует ли тип данных поведение, похожее на массив объектов. Каждый бит в этом члене — это флаг, имеющий следующие имена:
-
PyDataType_FLAGCHK(PyArray_Descr *dtype, int flags) -
Возвращает true, если все заданные флаги установлены для объекта типа данных.
-
PyDataType_REFCHK(PyArray_Descr *dtype) -
Эквивалентно
PyDataType_FLAGCHK(dtype,NPY_ITEM_REFCOUNT).
-
-
int PyArray_Descr.type_num -
Число, уникально идентифицирующее тип данных. Для новых типов данных это число назначается при регистрации типа данных.
-
int PyArray_Descr.elsize -
Для типов данных, которые всегда имеют одинаковый размер (например, long), это размер типа данных. Для гибких типов данных, где разные массивы могут иметь разные размеры элементов, это должно быть 0.
-
int PyArray_Descr.alignment -
Число, предоставляющее информацию об выравнивании для этого типа данных. В частности, оно показывает, как далеко от начала структуры из двух элементов (первый элемент которой —
char), компилятор помещает элемент этого типа:offsetof(struct {char c; type v;}, v)
-
PyArray_ArrayDescr *PyArray_Descr.subarray -
Если это не
NULL, то этот дескриптор типа данных представляет собой непрерывный массив C-стиля другого дескриптора типа данных. Другими словами, каждый элемент, описываемый этим дескриптором, фактически является массивом некоторого другого базового дескриптора. Это наиболее полезно в качестве дескриптора типа данных для поля в другом дескрипторе типа данных. Члены поля должны бытьNULLесли это неNULL(член поля базового дескриптора может быть неNULL, однако). СтруктураPyArray_ArrayDescrопределена с помощьюtypedef struct { PyArray_Descr *base; PyObject *shape; } PyArray_ArrayDescr;Элементы этой структуры:
-
PyArray_Descr *PyArray_ArrayDescr.base -
Объект дескриптора типа данных базового типа.
-
PyObject *PyArray_ArrayDescr.shape -
Форма (всегда непрерывная в стиле C) подмассива в виде кортежа Python.
-
-
PyObject *PyArray_Descr.fields -
Если это не NULL, то этот дескриптор типа данных имеет поля, описанные в словаре Python, ключами которого являются имена (а также заголовки, если они указаны), а значениями — кортежи, описывающие поля. Обратите внимание, что дескриптор типа данных всегда описывает фиксированный набор байтов. Поле — это именованная подобласть этого полного, фиксированного набора. Поле описывается кортежем, состоящим из другого дескриптора типа данных и смещения байта. По желанию, кортеж может содержать заголовок, который обычно является строкой Python. Эти кортежи размещаются в этом словаре с ключами по имени (и также по заголовку, если он указан).
-
PyArray_ArrFuncs *PyArray_Descr.f -
Указатель на структуру, содержащую функции, которые тип должен реализовывать для внутренних функций. Эти функции не являются тем же, что универсальные функции (ufuncs), описанные позже. Их сигнатуры могут произвольно отличаться.
-
PyArray_ArrFuncs -
Функции, реализующие внутренние возможности. Не все эти указатели на функции должны быть определены для данного типа. Требуемыми членами являются
nonzero,copyswap,copyswapn,setitem,getitem, иcast. Предполагается, что они неNULLиNULLзаписи приведут к аварийному завершению программы. Другие функции могут бытьNULLчто просто означает уменьшенную функциональность для этого типа данных. (Также, функция nonzero будет заполнена по умолчанию, если онаNULLпри регистрации пользовательского типа данных).typedef struct { PyArray_VectorUnaryFunc *cast[NPY_NTYPES]; PyArray_GetItemFunc *getitem; PyArray_SetItemFunc *setitem; PyArray_CopySwapNFunc *copyswapn; PyArray_CopySwapFunc *copyswap; PyArray_CompareFunc *compare; PyArray_ArgFunc *argmax; PyArray_DotFunc *dotfunc; PyArray_ScanFunc *scanfunc; PyArray_FromStrFunc *fromstr; PyArray_NonzeroFunc *nonzero; PyArray_FillFunc *fill; PyArray_FillWithScalarFunc *fillwithscalar; PyArray_SortFunc *sort[NPY_NSORTS]; PyArray_ArgSortFunc *argsort[NPY_NSORTS]; PyObject *castdict; PyArray_ScalarKindFunc *scalarkind; int **cancastscalarkindto; int *cancastto; PyArray_FastClipFunc *fastclip; PyArray_FastPutmaskFunc *fastputmask; PyArray_FastTakeFunc *fasttake; PyArray_ArgFunc *argmin; } PyArray_ArrFuncs;В описании указателей на функции используется понятие корректного сегмента. Корректный сегмент — это сегмент, выровненный и в родном порядке байтов для данного типа данных. Функции
nonzero,copyswap,copyswapn,getitem, иsetitemмогут (и должны) обрабатывать некорректные массивы. Другие функции требуют корректных участков памяти.-
void cast(void *from, void *to, npy_intp n, void *fromarr, void *toarr) -
Массив указателей на функции для преобразования из текущего типа во все другие встроенные типы. Каждая функция преобразует непрерывный, выровненный и необращенный буфер, указанный в from, в непрерывный, выровненный и необращенный буфер, указанный в to. Количество элементов для преобразования задаётся значением n, а аргументы fromarr и toarr интерпретируются как PyArrayObjects для гибких массивов, чтобы получить информацию о размере элемента.
-
PyObject *getitem(void *data, void *arr) -
Указатель на функцию, возвращающую стандартный объект Python из одного элемента объекта массива arr, на который указывает data. Эта функция должна уметь правильно обрабатывать «некорректные» (невыровненные и/или с изменённым порядком байтов) массивы.
-
int setitem(PyObject *item, void *data, void *arr) -
Указатель на функцию, устанавливающую объект Python item в массив arr в позиции, на которую указывает data. Эта функция обрабатывает «некорректные» массивы. При успешном выполнении возвращается ноль, в противном случае — минус один (и устанавливается ошибка Python).
-
void copyswapn(void *dest, npy_intp dstride, void *src, npy_intp sstride, npy_intp n, int swap, void *arr)
-
void copyswap(void *dest, void *src, int swap, void *arr) -
Эти члены — оба указателя на функции для копирования данных из src в dest и swap, если это указано. Значение arr используется только для гибких (
NPY_STRING,NPY_UNICODEиNPY_VOID) массивов (и получается изarr->descr->elsize). Вторая функция копирует одно значение, а первая повторяет эту операцию n раз со заданными шагами. Эти функции могут обрабатывать некорректные данные src. Если src равно NULL, то копирование не выполняется. Если swap равно 0, то перестановка байтов не происходит. Предполагается, что dest и src не перекрываются. Если они перекрываются, то сначала используйтеmemmove(…), а затемcopyswap(n)сsrcзначением NULL.
-
int compare(const void* d1, const void* d2, void* arr) -
Указатель на функцию, сравнивающую два элемента массива,
arr, указанных по адресуd1иd2. Эта функция требует корректных (выровненных и без перестановки байтов) массивов. Возвращаемое значение равно 1, если *d1> *d2, 0, если *d1== *d2, и -1, если *d1< *d2. Объект массиваarrиспользуется для получения информации о размере элемента и поле для гибких массивов.
-
int argmax(void* data, npy_intp n, npy_intp* max_ind, void* arr) -
Указатель на функцию, возвращающую индекс наибольшего из
nэлементов вarr, начиная с элемента, на который указываетdata. Эта функция требует, чтобы участок памяти был непрерывным и корректным. Возвращаемое значение всегда равно 0. Индекс наибольшего элемента возвращается вmax_ind.
-
void dotfunc(void* ip1, npy_intp is1, void* ip2, npy_intp is2, void* op, npy_intp n, void* arr) -
Указатель на функцию, которая перемножает две
n-длинные последовательности, складывает их и помещает результат в элемент, указанный по адресуopмассиваarr. Начало двух последовательностей указаны по адресамip1иip2. Для перехода к следующему элементу в каждой последовательности требуется перескок наis1иis2байтов, соответственно. Эта функция требует корректной (хотя и не обязательно непрерывной) памяти.
-
int scanfunc(FILE* fd, void* ip, void* sep, void* arr) -
Указатель на функцию, которая выполняет сканирование (подобно scanf) одного элемента соответствующего типа из дескриптора файла
fdв память массива, на которую указываетip. Массив предполагается корректным. Еслиsepне равно NULL, то также сканируется разделительная строка из файла перед возвратом. Последний аргументarr— массив, в который производится сканирование. Возвращается 0, если сканирование прошло успешно. Отрицательное число указывает на ошибку: -1 означает, что конец файла был достигнут до сканирования разделительной строки, -4 означает, что конец файла был достигнут до сканирования элемента, и -3 означает, что элемент не мог быть интерпретирован из строки формата. Требуется корректный массив.
-
int fromstr(char* str, void* ip, char** endptr, void* arr) -
Указатель на функцию, которая преобразует строку, на которую указывает
str, в один элемент соответствующего типа и помещает его в место в памяти, указанное по адресуip. После завершения преобразования*endptrуказывает на оставшуюся часть строки. Последний аргументarr— массив, в который указывает ip (необходим для массивов с переменным размером).
-
Bool nonzero(void* data, void* arr) -
Указатель на функцию, возвращающую TRUE, если элемент массива
arr, на который указываетdata, не равен нулю. Эта функция может обрабатывать некорректные массивы.
-
void fill(void* data, npy_intp length, void* arr) -
Указатель на функцию, заполняющую непрерывный массив заданной длины данными. Первые два элемента массива должны быть заполнены. Из этих двух значений будет вычислена разность, и значения с элемента 3 до конца будут вычисляться путём последовательного добавления этой разности. Буфер данных должен быть корректным.
-
void fillwithscalar(void* buffer, npy_intp length, void* value, void* arr) -
Указатель на функцию, заполняющую непрерывный
bufferзаданногоlengthс помощью одного скалярногоvalue, адрес которого указан. Последний аргумент — массив, необходимый для получения размера элемента для массивов переменной длины.
-
int sort(void* start, npy_intp length, void* arr) -
Массив указателей на функции для конкретного алгоритма сортировки. Конкретный алгоритм сортировки выбирается по ключу (на данный момент определены
NPY_QUICKSORT, :data`NPY_HEAPSORT`, иNPY_MERGESORT). Сортировка выполняется на месте, предполагается непрерывность и выравнивание данных.
-
int argsort(void* start, npy_intp* result, npy_intp length, void *arr) -
Массив указателей на функции сортировки для этого типа данных. Доступны те же алгоритмы сортировки, что и для sort. Индексы, порождающие сортировку, возвращаются в
result(который должен быть инициализирован индексами от 0 доlength-1включительно).
-
PyObject *castdict -
Либо
NULL, либо словарь, содержащий функции низкоуровневого преобразования для пользовательских типов данных. Каждая функция обернута вPyCObject *и имеет в качестве ключа номер типа данных.
-
NPY_SCALARKIND scalarkind(PyArrayObject* arr) -
Функция для определения того, как следует интерпретировать скаляры этого типа. Аргумент —
NULLили одномерный массив, содержащий данные (если это необходимо для определения типа скаляра). Возвращаемое значение должно иметь типNPY_SCALARKIND.
-
int **cancastscalarkindto -
Либо
NULL, либо массив указателейNPY_NSCALARKINDS. Каждый из этих указателей должен быть либоNULL, либо указателем на массив целых чисел (завершаемыхNPY_NOTYPE), указывающих на типы данных, в которые скаляр этого типа данных указанного типа может быть безопасно преобразован (обычно это означает без потери точности).
-
int *cancastto -
Либо
NULL, либо массив целых чисел (завершаемыйNPY_NOTYPE), указывающий на типы данных, в которые этот тип данных может быть безопасно преобразован (обычно это означает без потери точности).
-
void fastclip(void *in, npy_intp n_in, void *min, void *max, void *out) -
Функция, которая считывает
n_inэлементов изin, и записывает вoutсчитанное значение, если оно находится в пределах, указанных по адресамminиmax, или соответствующее ограничение, если оно находится вне пределов. Участки памяти должны быть непрерывными и корректными, и либоmin, либоmaxможет бытьNULL, но не оба одновременно.
-
-
void fastputmask(void *in, void *mask, npy_intp n_in, void *values, npy_intp nv) -
Функция, принимающая указатель
inна массив элементов типаn_in, указательmaskна массив булевых значений, и указательvalsна массив элементов типаnv. Элементы изvalsкопируются вinтам, где значение вmaskне равно нулю, с повторениемvalsпри необходимости, еслиnv < n_in. Все массивы должны быть непрерывными и вежливыми.
-
void fasttake(void *dest, void *src, npy_intp *indarray, npy_intp nindarray, npy_intp n_outer, npy_intp m_middle, npy_intp nelem, NPY_CLIPMODE clipmode) -
Функция, принимающая указатель
srcна непрерывный, вежливый фрагмент, интерпретируемый как 3-мерный массив формы(n_outer, nindarray, nelem), указательindarrayна непрерывный, вежливый фрагмент целочисленных индексов, и указательdestна непрерывный, вежливый фрагмент, интерпретируемый как 3-мерный массив формы(n_outer, m_middle, nelem). Индексы вindarrayиспользуются для индексированияsrcпо второму измерению, и копирования соответствующих фрагментов элементовnelemвdest.clipmode(которое может принимать значенияNPY_RAISE,NPY_WRAPилиNPY_CLIP) определяет, как будут обрабатываться индексы, меньшие 0 или большиеnindarray.
-
int argmin(void* data, npy_intp n, npy_intp* min_ind, void* arr) -
Указатель на функцию, которая возвращает индекс наименьшего из
nэлементов вarr, начиная с элемента, на который указываетdata. Эта функция требует, чтобы сегмент памяти был непрерывным и вежливым. Значение возврата всегда равно 0. Индекс наименьшего элемента возвращается вmin_ind.
-
Тип PyArray_Type реализует многие функции объектов Python, включая интерфейсы tp_as_number, tp_as_sequence, tp_as_mapping и tp_as_buffer. Также используется богатое сравнение (tp_richcompare), наряду с поиском атрибутов нового стиля для методов (tp_methods) и свойств (tp_getset). Тип PyArray_Type также может быть подтипом.
Подсказка
Методы tp_as_number используют общий подход для вызова любой функции, которая была зарегистрирована для обработки операции. Функция PyNumeric_SetOps(..) может использоваться для регистрации функций для обработки конкретных математических операций (для всех массивов). При импорте модуля umath, он устанавливает числовые операции для всех массивов на соответствующие ufuncs. Методы tp_str и tp_repr также могут быть изменены с помощью PyString_SetStringFunction(...).
PyUFunc_Type
-
PyUFuncObject -
Ядром ufunc является
PyUFuncObject, который содержит всю информацию, необходимую для вызова подлежащих C-кодовых циклов, выполняющих фактическую работу. Он имеет следующую структуру:typedef struct { PyObject_HEAD int nin; int nout; int nargs; int identity; PyUFuncGenericFunction *functions; void **data; int ntypes; int check_return; const char *name; char *types; const char *doc; void *ptr; PyObject *obj; PyObject *userloops; npy_uint32 *op_flags; npy_uint32 *iter_flags; } PyUFuncObject;-
int PyUFuncObject.nin -
Количество входных аргументов.
-
int PyUFuncObject.nout -
Количество выходных аргументов.
-
int PyUFuncObject.nargs -
Общее количество аргументов (nin + nout). Это значение должно быть меньше
NPY_MAXARGS.
-
int PyUFuncObject.identity -
Либо
PyUFunc_One, либоPyUFunc_Zero, либоPyUFunc_Noneдля обозначения единицы для этой операции. Она используется только для вызова типа reduce на пустом массиве.
-
void PyUFuncObject.functions(char** args, npy_intp* dims, -
npy_intp* steps, void* extradata) -
Массив указателей на функции — по одному для каждого поддерживаемого типа данных ufunc. Это цикл векторов, который вызывается для реализации подлежащей функции dims [0] раз. Первый аргумент, args, представляет собой массив из nargs указателей на вежливую память. Указатели на данные для входных аргументов находятся первыми, за ними следуют указатели на данные для выходных аргументов. Количество байтов, которое необходимо пропустить, чтобы получить следующий элемент в последовательности, задается соответствующим элементом в массиве steps. Последний аргумент позволяет циклу получать дополнительную информацию. Это обычно используется, чтобы один общий цикл векторов мог использоваться для нескольких функций. В этом случае фактическая скалярная функция, которую нужно вызвать, передается в качестве extradata. Размер этого массива указателей на функции равен ntypes.
-
void **PyUFuncObject.data -
Дополнительные данные, которые необходимо передать циклам векторов 1-d, или
NULLесли дополнительные данные не нужны. Этот массив C должен быть того же размера (т.е. ntypes) что и массив функций.NULLиспользуется, если дополнительные данные не нужны. Несколько вызовов C-API для UFuncs представляют собой циклы векторов 1-d, которые используют эти дополнительные данные для получения указателя на фактическую вызываемую функцию.
-
int PyUFuncObject.ntypes -
Количество поддерживаемых типов данных для ufunc. Это число определяет количество различных циклов 1-d (встроенных типов данных), которые доступны.
-
int PyUFuncObject.check_return -
Устаревший и неиспользуемый. Однако он устанавливается соответствующим элементом в основной процедуре создания ufunc:
PyUFunc_FromFuncAndData(...).
-
char *PyUFuncObject.name -
Строковое имя для ufunc. Это используется динамически для построения атрибута __doc__ для ufuncs.
-
char *PyUFuncObject.types -
Массив из nargs
ntypes 8-битных номеров типов, который содержит сигнатуру типа для функции для каждого из поддерживаемых (встроенных) типов данных. Для каждой из ntypes функций, соответствующий набор номеров типов в этом массиве показывает, как аргумент args должен интерпретироваться в цикле векторов 1-d. Эти номера типов не должны быть одинаковыми, и ufuncs смешанных типов поддерживаются.
-
char *PyUFuncObject.doc -
Документация для ufunc. Не должна содержать сигнатуру функции, так как она генерируется динамически при получении __doc__.
-
void *PyUFuncObject.ptr -
Любая динамически выделенная память. В настоящее время используется для динамически созданных ufuncs из python-функций для хранения места для членов types, data и name.
-
PyObject *PyUFuncObject.obj -
Для ufuncs, динамически созданных из python-функций, этот член содержит ссылку на подлежащую Python-функцию.
-
PyObject *PyUFuncObject.userloops -
Словарь пользовательских циклов векторов 1-d (хранящихся как указатели CObject) для пользовательских типов. Пользователь может зарегистрировать цикл для любого пользовательского типа. Он извлекается по номеру типа. Номера типов пользовательского определения всегда больше
NPY_USERDEF.
-
npy_uint32 PyUFuncObject.op_flags -
Переопределяет флаги операндов по умолчанию для каждого операнда ufunc.
-
npy_uint32 PyUFuncObject.iter_flags -
Переопределяет флаги nditer по умолчанию для ufunc.
-
PyArrayIter_Type
-
PyArrayIterObject -
Структура C, соответствующая объекту
PyArrayIter_Type— этоPyArrayIterObject.PyArrayIterObjectиспользуется для отслеживания указателя на элемент N-мерного массива. Он содержит связанную информацию, используемую для быстрого перемещения по массиву. Указатель можно изменить тремя основными способами: 1) перейти к следующему элементу массива в стиле C с последовательным доступом, 2) перейти к произвочным N-мерным координатам в массиве и 3) перейти к произвольному одномерному индексу в массиве. Члены структурыPyArrayIterObjectиспользуются в этих расчётах. Объекты-итераторы сохраняют собственные размерности и шаги массива. Это можно изменять по мере необходимости для «вещания» или для обхода только определённых измерений.typedef struct { PyObject_HEAD int nd_m1; npy_intp index; npy_intp size; npy_intp coordinates[NPY_MAXDIMS]; npy_intp dims_m1[NPY_MAXDIMS]; npy_intp strides[NPY_MAXDIMS]; npy_intp backstrides[NPY_MAXDIMS]; npy_intp factors[NPY_MAXDIMS]; PyArrayObject *ao; char *dataptr; Bool contiguous; } PyArrayIterObject;-
int PyArrayIterObject.nd_m1 -
где
— количество измерений в базовом массиве.
-
npy_intp PyArrayIterObject.index -
Текущий одномерный индекс в массиве.
-
npy_intp PyArrayIterObject.size -
Общий размер базового массива.
-
npy_intp *PyArrayIterObject.coordinates -
N-мерный индекс в массиве.
-
npy_intp *PyArrayIterObject.dims_m1 -
Размер массива минус 1 в каждом измерении.
-
npy_intp *PyArrayIterObject.strides -
Шаги массива. Сколько байт нужно перейти к следующему элементу в каждом измерении.
-
npy_intp *PyArrayIterObject.backstrides -
Сколько байт нужно перейти от конца измерения к его началу. Обратите внимание, что backstrides [k]= strides [k]*d ims_m1 [k], но это хранится здесь для оптимизации.
-
npy_intp *PyArrayIterObject.factors -
Этот массив используется для вычисления N-мерного индекса из одномерного индекса. Он содержит необходимые произведения размерностей.
-
PyArrayObject *PyArrayIterObject.ao -
Указатель на базовый ndarray, для представления которого был создан этот итератор.
-
char *PyArrayIterObject.dataptr -
Этот член указывает на элемент в ndarray, указанный индексом.
-
Bool PyArrayIterObject.contiguous -
Этот флаг имеет значение true, если базовый массив является
NPY_ARRAY_C_CONTIGUOUS. Он используется для упрощения расчётов, когда это возможно.
-
Более подробное объяснение использования итератора массива на уровне C приведено в следующих разделах. Как правило, вам не нужно беспокоиться о внутренней структуре объекта-итератора, а просто взаимодействовать с ним с помощью макросов PyArray_ITER_NEXT (it), PyArray_ITER_GOTO (it, dest) или PyArray_ITER_GOTO1D (it, index). Все эти макросы требуют аргумента it, который должен быть PyArrayIterObject *.
PyArrayMultiIter_Type
-
PyArrayMultiIterObject -
typedef struct { PyObject_HEAD int numiter; npy_intp size; npy_intp index; int nd; npy_intp dimensions[NPY_MAXDIMS]; PyArrayIterObject *iters[NPY_MAXDIMS]; } PyArrayMultiIterObject;-
int PyArrayMultiIterObject.numiter -
Количество массивов, которые необходимо привести к одному размеру.
-
npy_intp PyArrayMultiIterObject.size -
Общий размер после вещания.
-
npy_intp PyArrayMultiIterObject.index -
Текущий (одномерный) индекс в результирующем массиве после вещания.
-
int PyArrayMultiIterObject.nd -
Количество измерений в результирующем массиве после вещания.
-
npy_intp *PyArrayMultiIterObject.dimensions -
Размеры результирующего массива после вещания (используются только
ndслоты).
-
PyArrayIterObject **PyArrayMultiIterObject.iters -
Массив объектов-итераторов, содержащий итераторы для массивов, которые необходимо привести к одному размеру. После возвращения итераторы корректируются для вещания.
-
PyArrayNeighborhoodIter_Type
-
PyArrayNeighborhoodIterObject -
Структура C, соответствующая объекту
PyArrayNeighborhoodIter_Type— этоPyArrayNeighborhoodIterObject.
PyArrayFlags_Type
Типы скалярных массивов
Для каждого из встроенных типов данных, которые могут присутствовать в массиве, существует тип Python. Большинство из них являются простыми оболочками соответствующего типа данных в C. Имена типов в C — это Py{TYPE}ArrType_Type , где {TYPE} может быть
Эти имена типов являются частью C-API и поэтому могут быть созданы в коде расширения C. Также есть PyIntpArrType_Type и PyUIntpArrType_Type, которые являются простыми заменителями одного из целочисленных типов, который может содержать указатель на платформе. Структура этих скалярных объектов не раскрывается коду C. Функция PyArray_ScalarAsCtype (..) может использоваться для извлечения значения типа C из скаляра массива, а функция PyArray_Scalar (...) может использоваться для построения скаляра массива из значения C.
Другие структуры C
Несколько новых структур C оказались полезными при разработке NumPy. Эти структуры C используются как минимум в одном вызове C-API и поэтому документированы здесь. Основная причина определения этих структур — упрощение использования Python ParseTuple C-API для преобразования из объектов Python в полезный объект C.
PyArray_Dims
-
PyArray_Dims -
Эта структура очень полезна, когда требуется интерпретация информации о форме и/или шагах. Структура:
typedef struct { npy_intp *ptr; int len; } PyArray_Dims;Члены этой структуры:
-
npy_intp *PyArray_Dims.ptr -
Указатель на список (
npy_intp) целых чисел, которые обычно представляют форму массива или шаги массива.
-
int PyArray_Dims.len -
Длина списка целых чисел. Предполагается, что доступ к ptr [0] до ptr [len-1] безопасен.
-
PyArray_Chunk
-
PyArray_Chunk -
Это эквивалентно структуре объекта буфера в Python до члена ptr. На 32-битных платформах (т.е. если
NPY_SIZEOF_INT==NPY_SIZEOF_INTP), член len также соответствует эквивалентному члену объекта буфера. Он полезен для представления общего односегментного блока памяти.typedef struct { PyObject_HEAD PyObject *base; void *ptr; npy_intp len; int flags; } PyArray_Chunk;Члены:
-
PyObject *PyArray_Chunk.base -
Объект Python, из которого происходит этот блок памяти. Необходимо, чтобы память учитывалась должным образом.
-
void *PyArray_Chunk.ptr -
Указатель на начало односегментного блока памяти.
-
npy_intp PyArray_Chunk.len -
Длина сегмента в байтах.
-
int PyArray_Chunk.flags -
Любые флаги данных (например,
NPY_ARRAY_WRITEABLE), которые должны использоваться для интерпретации памяти.
-
PyArrayInterface
См. также
-
PyArrayInterface -
Структура
PyArrayInterfaceопределена для того, чтобы модули NumPy и другие расширяющие модули могли использовать протокол быстрого интерфейса массивов. Метод__array_struct__объекта, поддерживающего протокол быстрого интерфейса массивов, должен возвращатьPyCObject, содержащий указатель на структуруPyArrayInterfaceс соответствующими деталями массива. После создания нового массива атрибут должен бытьDECREF, что освободит структуруPyArrayInterface. Не забудьтеINCREFобъект (чей атрибут__array_struct__был получен) и укажите член base новогоPyArrayObjectна этот же объект. Таким образом память для массива будет управляться правильно.typedef struct { int two; int nd; char typekind; int itemsize; int flags; npy_intp *shape; npy_intp *strides; void *data; PyObject *descr; } PyArrayInterface;-
int PyArrayInterface.two -
целое число 2 в качестве проверки на корректность.
-
int PyArrayInterface.nd -
количество измерений в массиве.
-
char PyArrayInterface.typekind -
Символ, указывающий на тип массива в соответствии с соглашением о типах: ‘t’ -> битовое поле, ‘b’ -> булево, ‘i’ -> целое со знаком, ‘u’ -> целое без знака, ‘f’ -> с плавающей точкой, ‘c’ -> комплексное с плавающей точкой, ‘O’ -> объект, ‘S’ -> (байтовый) строка, ‘U’ -> Юникод, ‘V’ -> пустое.
-
int PyArrayInterface.itemsize -
Количество байтов, занимаемых каждым элементом в массиве.
-
int PyArrayInterface.flags -
Любой из битов
NPY_ARRAY_C_CONTIGUOUS(1),NPY_ARRAY_F_CONTIGUOUS(2),NPY_ARRAY_ALIGNED(0x100),NPY_ARRAY_NOTSWAPPED(0x200), илиNPY_ARRAY_WRITEABLE(0x400) для указания информации о данных. ФлагиNPY_ARRAY_ALIGNED,NPY_ARRAY_C_CONTIGUOUSиNPY_ARRAY_F_CONTIGUOUSмогут быть фактически определены из других параметров. ФлагNPY_ARR_HAS_DESCR(0x800) также может быть установлен для указания объектам, потребляющим интерфейс массива версии 3, что член descr структуры присутствует (он будет проигнорирован объектами, потребляющими интерфейс массива версии 2).
-
npy_intp *PyArrayInterface.shape -
Массив, содержащий размер массива в каждом измерении.
-
npy_intp *PyArrayInterface.strides -
Массив, содержащий количество байтов, которые нужно пропустить, чтобы перейти к следующему элементу в каждом измерении.
-
void *PyArrayInterface.data -
Указатель на первый элемент массива.
-
PyObject *PyArrayInterface.descr -
Объект Python, описывающий тип данных более подробно (такой же, как ключ descr в
__array_interface__). Это поле может бытьNULL, если typekind и itemsize предоставляют достаточную информацию. Это поле также игнорируется, если флагARR_HAS_DESCRустановлен в flags.
-
Внутренние структуры
Внутренне код использует некоторые дополнительные объекты Python, предназначенные в первую очередь для управления памятью. Эти типы недоступны напрямую из Python и не экспонируются в C-API. Они включены здесь только для полноты и помощи в понимании кода.
-
PyUFuncLoopObject -
Условный оболочка C-структуры, содержащей информацию, необходимую для циклических операций. Это полезно, если вы пытаетесь понять код циклов ufunc.
PyUFuncLoopObject— это соответствующая C-структура. Она определена в заголовкеufuncobject.h.
-
PyUFuncReduceObject -
Условная оболочка C-структуры, содержащей информацию, необходимую для методов типа reduce для ufunc. Это полезно, если вы пытаетесь понять код reduce, accumulate и reduce-at.
PyUFuncReduceObject— это соответствующая C-структура. Она определена в заголовкеufuncobject.h.
-
PyUFunc_Loop1d -
Простая связанная цепочка C-структур, содержащих информацию, необходимую для определения цикла 1-d для ufunc для каждой определенной подписи пользовательского типа данных.
© 2008–2016 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.10.1/reference/c-api.types-and-structures.html