2010-09-24 15 views
10

Ich habe eine Ctypes-Struktur.Python: Können wir eine Ctypes-Struktur in ein Wörterbuch umwandeln?

class S1 (ctypes.Structure): 
    _fields_ = [ 
    ('A',  ctypes.c_uint16 * 10), 
    ('B',  ctypes.c_uint32), 
    ('C',  ctypes.c_uint32) ] 

wenn ich X = S1(), würde Ich mag ein Wörterbuch zurück aus diesem Objekt: Beispiel, wenn ich etwas tun: Y = X.getdict() oder Y = getdict (X) , dann könnte Y aussehen wie:

{ 'A': [1,2,3,4,5,6,7,8,9,0], 
    'B': 56, 
    'C': 8986 } 

Irgendwelche Hilfe?

+1

BTW, gibt es einen Grund, warum Sie ein echtes "dict" -Objekt brauchen und nicht einfach '__getitem __()' usw. Methoden zu Ihren Strukturklassen hinzufügen können? – llasram

+0

In meinem Fall wollte ich ein Diktat mit Daten über Prozesse auf einem System ... so machte es mehr Sinn, es in ein Diktat der Diktate zu setzen – RobotHumans

Antwort

10

Wahrscheinlich so etwas wie dieses:

def getdict(struct): 
    return dict((field, getattr(struct, field)) for field, _ in struct._fields_) 

>>> x = S1() 
>>> getdict(x) 
{'A': <__main__.c_ushort_Array_10 object at 0x100490680>, 'C': 0L, 'B': 0L} 

Wie Sie sehen können, funktioniert es mit Zahlen, aber es ist nicht so schön mit Arrays arbeiten - Sie kümmern Arrays umzuwandeln, sich Listen zu nehmen haben. Eine anspruchsvollere Version, die Arrays zu konvertieren versucht ist wie folgt:

def getdict(struct): 
    result = {} 
    for field, _ in struct._fields_: 
     value = getattr(struct, field) 
     # if the type is not a primitive and it evaluates to False ... 
     if (type(value) not in [int, long, float, bool]) and not bool(value): 
      # it's a null pointer 
      value = None 
     elif hasattr(value, "_length_") and hasattr(value, "_type_"): 
      # Probably an array 
      value = list(value) 
     elif hasattr(value, "_fields_"): 
      # Probably another struct 
      value = getdict(value) 
     result[field] = value 
    return result 

Wenn Sie numpy haben und wollen in der Lage sein, multidimensionale C-Arrays zu handhaben, sollten Sie import numpy as np und Änderung hinzu:

value = list(value) 

zu :

value = np.ctypeslib.as_array(value).tolist() 

Dies wird Ihnen eine verschachtelte Liste geben.

+0

Nizza! Fast da. Ich stehe immer noch vor einer neuen Situation, in der eine C-Typ-Struktur S1 ein Feld eines anderen Typs S2 hat. Frage mich, ob das auch konvertiert werden kann. –

+0

Ich habe eine weitere Verzweigung hinzugefügt, die versucht, geschachtelte Strukturen zu handhaben (angenommen, dass Strukturen durch ihr '_fields_' Attribut erkannt werden können). Nicht sicher, ob das funktioniert, aber ich habe es nicht getestet. –

+0

Wird getestet und Sie wissen lassen. Vielen Dank. –

2

Wie wäre es so etwas wie:

class S1(ctypes.Structure): 
    _fields_ = [ ... ] 

    def getdict(self): 
     dict((f, getattr(self, f)) for f, _ in self._fields_) 
1

Ein wenig mehr Allzweck-Doppel Arrays und Arrays von Strukturen und Bitfelder zu handhaben.

Verwandte Themen