Domanda

Quale sarebbe il modo migliore per l'estrazione, una stringa di pitone in campi

Non ho i dati ricevuti da un socket TCP, è imballato come segue, credo che sarà in una stringa dalla funzione recv presa

Ha il seguente formato

uint8 - intestazione
uint8 - Lunghezza
uint32 - TypeId
UINT16 -param1
UINT16 -param2
UINT16 -param3
UINT16 -param4
char [24] - nome della stringa
uint32 - checksum
uint8 - piè di pagina

(Ho anche bisogno di decomprimere altri pacchetti con diversi formati a quanto sopra)

Come faccio a decomprimere questi?

Sono nuovo di pitone, hanno fatto un po 'di 'C'. Se stavo usando 'C' Io probabilmente utilizzare una struttura, questo sarebbe il modo di andare con Python?

Saluti

X

È stato utile?

Soluzione

Il modulo struct è stato progettato per decomprimere i dati eterogenei ad una tupla in base a una stringa di formato. Ha più senso per decomprimere l'intero struct in una volta, piuttosto che cercare di tirare fuori un solo campo alla volta. Ecco un esempio:

fields = struct.unpack('!BBI4H20sIB', data)

Poi si può accedere a un determinato campo, ad esempio, il primo campo:

fields[0]

Si potrebbe anche usare la tupla per inizializzare un namedtuple; guardare il per struct per un esempio. NamedTuples sono disponibili solo in Python 2.6+, ma si comportano più come strutture Python in quanto è possibile accedere agli elementi come attributi, per esempio fields.header. Naturalmente, si potrebbe anche fare questo con un po 'più di lavoro, scrivendo una classe per incapsulare le informazioni dal tupla ... ancora una volta, se vi interessa. Si può sempre e solo indice in campi direttamente, come ho mostrato in precedenza.

Altri suggerimenti

struct modulo

Questa è una risposta alla tua domanda-come-una-risposta:

Non si può certo essere il modo migliore, perché non funziona. struct.unpack() restituisce sempre una tupla. Per strappare il singolo elemento in quella tupla, è necessario effettuare una field1 = struct.unpack('B',data[0])[0] o field1, = struct.unpack('B',data[0]).

Anche con questo fix, non è un buon modo: troppo digitazione, errori predisposizione di inutili [start: end]., L'inefficienza di 10 chiamate di funzione al posto di uno

Come avete nomi, si possono usare al posto di field1 o di un campo [0] ... in questo modo:

(header, length, typeID, param1, param2,
param3, param4, name_string, checksum, footer,
) = struct.unpack("!2B I 4H 24s I B", data)

E 'questo il modo migliore di fare questo o c'è un modo migliore

E 'probabile che ci saranno le stringhe con altri formati che richiederanno uno schema diverso disimballaggio

field1 = struct.unpack ( 'B', i dati [0])
field2 = struct.unpack ( 'B', i dati [1])
field3 = struct.unpack (dati [2: 6] 'I!')
Campo4 = struct.unpack ( '! H', i dati [6: 8])
Field5 = struct.unpack ( '! H', i dati [08:10])
field6 = struct.unpack ( '! H', i dati [10:12])
field7 = struct.unpack ( '! H', i dati [00:14])
Field8 = struct.unpack (anni '20 ", i dati [14:38])
field9 = struct.unpack ( '! I', i dati [38:42])
field10 = struct.unpack ( 'B', i dati [42])

Saluti

Date un'occhiata al modulo ' struct '.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top