Я пытаюсь написать метод __reduce__()
для класса cython, который содержит указатели C, но до сих пор нашел очень мало информации о том, как это сделать. Существует множество примеров для правильного написания метода __reduce__()
при использовании массивов numpy в качестве данных элемента. Я хотел бы держаться подальше от массивов Numpy, поскольку они, как представляется, всегда хранятся как объекты python и требуют вызова API-интерфейса python и из него. Я исхожу из C-фона, поэтому я очень комфортно работаю с памятью вручную, используя вызовы malloc()
и free()
, и стараюсь поддерживать взаимодействие python с абсолютным минимумом.Pickle Cython Class с C указателями
Однако я столкнулся с проблемой. Мне нужно использовать что-то эквивалентное copy.deepcopy()
для класса, который я создаю, из сценария Python, где он будет в конечном счете использоваться. Я обнаружил, что единственный хороший способ сделать это - реализовать протокол pickle для класса, внедряя метод __reduce__()
. Это тривиально с большинством примитивов или объектов python. Однако я нахожусь в абсолютной потере для того, как это сделать для динамически распределенных массивов C. Очевидно, я не могу вернуть сам указатель, поскольку базовая память исчезнет к тому моменту, когда объект будет реконструирован, так что лучший способ сделать это? Я уверен, что это потребует модификации метода __reduce__()
, а также одного или обоих методов __init__()
.
Я прочитал документацию по python по типам растягивающих линий found here, а также почти каждый вопрос о переполнении стека о выборе классов cython, таких как this question.
Сокращенный вариант моего класса выглядит примерно так:
cdef class Bin:
cdef int* job_ids
cdef int* jobs
cdef int primitive_data
def __cinit__(self):
self.job_ids = <int*>malloc(40 * sizeof(int))
self.jobs = <int*>malloc(40 * sizeof(int))
def __init__(self, int val):
self.primitive_data = val
def __dealloc__(self):
free(job_ids)
free(jobs)
def __reduce__(self):
return (self.__class__, (self.primitive_data))
Я также читал этот вопрос, но она непосредственно не относится к _pickling_ указателей C массивы. [Cython - преобразование указателей на массивы в объекты Python] (http://stackoverflow.com/questions/5271690/cython-converting-pointers-to-arrays-into-python-objects?rq=1) –
Думаю, вам нужно сериализуйте данные в объект 'bytes' Python. Затем используйте функцию перестроения (например, http://stackoverflow.com/a/12647497/1300519) для возврата в массив int. Мне еще этого не удалось, но я считаю, что это правильный подход. Не публиковать это как ответ, пока у меня не будет рабочего примера. – Snorfalorpagus