2015-11-22 5 views
6

mi piacerebbe avere una matrice Cython di una classe cdef:Cython: come si fa a creare un array di classe cdef

cdef class Child: 
    cdef int i 

    def do(self): 
     self.i += 1 

cdef class Mother: 
    cdef Child[:] array_of_child 

    def __init__(self): 
     for i in range(100): 
      self.array_of_child[i] = Child() 
+1

Hai qualche motivo per credere che la mia risposta non sia aggiornata? Ho dato un'occhiata al changelog e non riesco a vedere nulla di ovvio lì. Penso che ci siano buone ragioni tecniche per cui è improbabile che questo cambi. – DavidW

+0

Cosa intendi con "array cython di una classe cdef"? Corrisponde a 'Child a [n]' di C++ per alcuni 'n' o' Child * '? Ci sono ovviamente alcuni problemi nel codice (dovrebbe essere 'self.array_of_child', la memoria per' array_of_child' dovrebbe essere allocata e quindi liberata), quindi forse la risoluzione di questi problemi renderà più chiaro ciò che si tenta di ottenere. – ead

risposta

8

Penso che la risposta è no: newsgroup post of essentially the same question

In sostanza, l'array dovrebbe essere una serie di puntatori al tuo Child, piuttosto che una matrice diretta di Child s. È così che deve essere sempre così perché da qualche altra parte si ottiene sempre un riferimento a un Child nell'array, che Child deve essere mantenuto attivo (ma non l'intero array) che non sarebbe realmente possibile se occupassero lo stesso blocco di memoria.

Il workround suggerito nel post di newsgroup è solo per usare una lista python. È anche possibile utilizzare un array numpy con dtype=object. Se è necessario per accedere ad una funzione cdef nella classe che si può fare un cast prima:

cdef Child c = <Child?>a[0] # omit the ? if you don't want 
          # the overhead of checking the type. 
c.some_cdef_function() 

Un'ulteriore possibilità potrebbe essere quella di memorizzare i dati come una struct C (cdef struct ChildStruct: ....), che può essere facilmente memorizzato come una matrice . Quando hai bisogno di un'interfaccia Python per quella struttura puoi definire Child in modo che contenga una copia di ChildStruct (ma le modifiche non si propagheranno all'array originale) o un puntatore a ChildStruct (ma devi stare attento a garantire che la memoria non viene liberata che il Child che punta ad esso è vivo).

Problemi correlati