Ich versuche, eine __reduce__()
-Methode für eine Cython-Klasse zu schreiben, die C-Zeiger enthält, aber bis jetzt sehr wenig Informationen über den besten Weg gefunden haben, dies zu tun. Es gibt Unmengen von Beispielen dafür, wie man eine __reduce__()
-Methode richtig schreibt, wenn man numpy-Arrays als Mitgliedsdaten verwendet. Ich möchte mich von Numpy-Arrays fernhalten, da sie immer als Python-Objekte gespeichert sind und Aufrufe von und an die Python-API erfordern. Ich komme von einem C-Hintergrund, also bin ich sehr komfortabel mit dem Speicher arbeiten manuell mit Calls zu malloc()
und free()
und versuche, Python Interaktion auf ein absolutes Minimum zu halten.Pickle Cython-Klasse mit C-Zeigern
Allerdings habe ich ein Problem festgestellt. Ich muss etwas Ähnliches wie copy.deepcopy()
für die Klasse, die ich erstelle, aus dem Python-Skript verwenden, wo es letztendlich verwendet wird. Ich habe gefunden, dass der einzige gute Weg dies zu tun ist, das Beizprotokoll für die Klasse zu implementieren, indem man eine __reduce__()
Methode einführt. Dies ist bei den meisten Primitiven oder Python-Objekten trivial. Ich bin jedoch absolut im Verlust, wie ich dies für dynamisch zugewiesene C-Arrays tun kann. Offensichtlich kann ich den Zeiger selbst nicht zurückgeben, da der zugrunde liegende Speicher zum Zeitpunkt der Rekonstruktion des Objekts verschwunden ist. Was ist der beste Weg, dies zu tun? Ich bin mir sicher, dass dies sowohl eine Modifikation der __reduce__()
-Methode als auch eine oder beide der __init__()
-Methoden erfordert.
Ich habe die Python-Dokumentation über Beizen Erweiterungstypen found here sowie fast jede andere Frage des Stacküberlaufs über die Auswahl von Cython-Klassen wie this question gelesen.
Eine komprimierte Version meiner Klasse sieht ungefähr so aus:
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))
ich auch diese Frage gelesen habe, aber es gilt nicht direkt C Zeiger auf Arrays _pickling_. [Cython - Zeiger auf Arrays in Python-Objekte konvertieren] (http://stackoverflow.com/questions/5271690/cython-converting-pointers-to-arrays-into-python-objects?rq=1) –
Ich denke, Sie müssen Serialisieren Sie die Daten in ein Python-bytes-Objekt. Verwenden Sie dann eine Neuerstellungsfunktion (z. B. http://stackoverflow.com/a/12647497/1300519), um in ein int-Array zurückzuspringen. Ich habe es noch nicht geschafft, das selbst zu schaffen, aber ich glaube, das ist der richtige Ansatz. Ich schreibe das nicht als Antwort, bis ich ein funktionierendes Beispiel habe. – Snorfalorpagus