[Python] Maneggiare i byte

Daniele Varrazzo piro a develer.com
Gio 25 Set 2008 01:26:38 CEST



On Wed, 24 Sep 2008 19:22:10 +0200, michele a nectarine.it wrote:
> 2008/9/24 Enrico Franchi <enrico.franchi a gmail.com>:
>>> Supponiamo di leggere un file binario:
>>>
>>> fd = open('/tmp/foo','rb')
>>> cont = fd.read()
>>> fd.close()
>>>
>>> Ora, le mie domande sono: come si possono estrarre 5 byte da quella
>>> stringa evitando di utilizzare file.seek() e file.read()?
>>> Nel senso: ho a disposizione un tipo stringa che contiene dei byte
>>> di dati.
>>>   - Come posso ottenere delle 'fette' di dati?
>>>   - Come posso ottenere la lunghezza in byte di questi dati?
>>
>> Quello che ti dicevo riguardo al leggere un manuale. Le stringhe sono
>> sliceabili.
>> Sono proprio fatte apposta per prenderne delle fette.
>>
>> s[2:7]
> 
> Conoscevo dello slicing delle stringhe in stile MATLAB, ma quello che  
> non capisco è se c'è una corrispondenza 1:1 tra s[i] e un byte del mio 

> file.
> Se sì, a questo punto posso maneggiare senza problemi ogni byte del  
> mio file, in quanto ogni byte è un carattere della mia stringa.
> O sono costretto ad usare il modulo struct di cui parlava Giorgio Zoppi?

Sì, c'è una corrispondenza 1-1 tra byte e caratteri, visto che (in python
2.x) un oggetto str è una stringa di caratteri a 8 bit.

Il modulo struct non ti serve: quello serve a convertire da strutture dati
C (es. con dentro unt32, uint16...) a oggetti Python.

>> Io *non* erediterei da lista in generale. In particolare lista non è
>> la classe giusta di partenza.
>> Una lista ha un fottio di cose più di un BitSet, e sono cose che
>> ovviamente paghi in spazio e in tempo.
>> In secondo luogo io *non* userei l'ereditarietà, ma la composizione.
> 
> Vero, errore mio. Al posto dell'ereditarietà è meglio usare la  
> composizione, hai ragione.
> 
>> Per rimanere in pure-python io userei probabilmente composizione con
>> array.
>> Ovviamente occupa molto più spazio di un bitset fatto di bit (ma
>> dovrebbe anche essere più veloce).
> 
> Ok, un array di tipi bool True/False.

Prenderei in considerazione numpy, che mette a disposizione un oggetto
array (numerico, ma può essere anche bool) e di effettuarci operazioni in
blocco. Se hai familiarità con matlab, c'è da sentirsi a casa.

Es: operazioni booleane sull'array completo:

    In [1]: import numpy

    In [2]: a = numpy.array([1,1,0,0], dtype=bool)

    In [3]: b = numpy.array([1,0,1,0], dtype=bool)

    In [4]: a | b
    Out[4]: array([ True,  True,  True, False], dtype=bool)

    In [5]: a & b
    Out[5]: array([ True, False, False, False], dtype=bool)

    In [6]: ~a
    Out[6]: array([False, False,  True,  True], dtype=bool)

Ovviamente c'è anche la possibilità di leggere un file in un array senza
passare per la stringa, e anche gli array supportano lo slicing
(multidimensionale, come quelli del matlab).

Divertiti!

-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


Maggiori informazioni sulla lista Python