Сообщение об ошибке «Не удается преобразовать« double * »в объект Python» в Cython - PullRequest
0 голосов
/ 13 декабря 2018

С этим сообщением об ошибках возникает много вопросов, но примеры не являются минимальными, поэтому ...

Когда я цитирую следующий Cython-модуль

%%cython
cdef double *ptr=[1,2,3]
print(ptr)

Iполучить следующее сообщение об ошибке:

Невозможно преобразовать 'double *' в объект Python

Однако для следующего модуля Cython:

%%cython
cdef double val=0.0
print(val)

Цитонизируется без проблем.

Эта проблема возникает также для любого другого типа указателя (например, int *, float * и т. д.).

1 Ответ

0 голосов
/ 13 декабря 2018

print - это чистая функция Python, и для возможности ее вызова аргументы должны быть объектами Python.

Очевидно, что ни ptr в первом модуле Cython, ни valво втором - объекты Python.Однако есть разница: переменная cdef типа double может быть автоматически преобразована в Python-Float с помощью Cython с помощью PyFloat_FromDouble - и это именно то, что происходит под капотом: Cython создаетвременный Python-Float из val, передает его в print и впоследствии уничтожает.

Существуют другие типы, которые могут автоматически преобразовываться в объекты Python: double, float, int и аналогичные, но также std::vector и другие c ++ - контейнеры .

Однако такого автоматического преобразования для необработанных указателей C не существует, поскольку это невозможно сделать вВо-первых, поскольку Cython не знает длину массива (это вообще массив?), на который указывает указатель.

Единственное решение в этом случае: нужно вручную преобразовать содержимоепамять для списка Python (или для любого другого типа Python), например, функция convert_to_python:

%%cython 
cdef convert_to_python(double *ptr, int n):
    cdef int i
    lst=[]
    for i in range(n):
        lst.append(ptr[i])
    return lst

cdef double *ptr=[1,2,3]
print(convert_to_python(ptr,3))

Самое замечательное, что convert_to_python получает количество элементовкак параграфметра - информация о Cython отсутствует.

Кстати: Cython автоматически преобразует C-массивы с известной длиной в объекты Python, например:

%%cython 
cdef double arr[3] # length (=3) known to Cython 
arr[:]=[1,2,3]
print(arr)

компилируется без проблем.

...