[Python] Maneggiare i byte

Enrico Franchi enrico.franchi a gmail.com
Mer 24 Set 2008 11:12:03 CEST


On Sep 24, 2008, at 10:31 AM, michele a nectarine.it wrote:

> dopo essere stato un fedele devoto al linguaggio Java ho deciso di
> provare il Python.

È un male essere "fedeli devoti". Ad un linguaggio poi... :P


> Dopo aver provato un po' per conto mio, mi sono nate due domande in  
> testa.
> 1) Spulciando tra i vari tipi predefiniti ho scoperto che non c'è il
> tipo 'byte', come invece accade in Java.

Ci sono tante di quelle differenze...

> Come ci si comporta?

Dipende da quello che vuoi fare. Leggere per bene un manuale stra-aiuta.


> Supponiamo di leggere un file binario:
>
> fd = open('/tmp/foo','rb')
> cont = fd.read()
> fd.close()
>
> ora, utilizzando print str(cont.__class__) (so che è una pessima
> pratica, ma altrimenti come si può sapere di che tipo è la variabile
> che contiene il file letto?), scopro che è un tipo string:
> <type 'str'>

Per sapere la classe di qualcosa, basta fare type(qualcosa).


> 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]

et similia. Prendi ipython e fatti delle belle prove (puoi anche  
prendere fette con passo con s[1:2:9])
La lunghezza in caratteri la prendi con len(s).


> 2)
> Come si può implementare un BitSet? (rif.
> http://java.sun.com/j2se/1.4.2/docs/api/java/util/BitSet.html )
> Ho pensato ad una sottoclasse di list, facendo un overriding dei
> metodi di insert, remove, iterator, etc.
> Voi che ne dite?

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.

Sicuramente una lista non è un bitset, visto che ad un bitset non puoi  
aggiungere e togliere elementi come fai in una lista.

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).

Questo se vuoi l'oggetto a livello didattico per vedere come si fa a  
farlo. Se vuoi un oggetto che manipoli i bit io lo scriverei  
appoggiandomi a C, wrappando con ctypes oppure usando direttamente le  
API C di Python. IMHO usare ctypes rende il tutto sbaloriditivamente  
banale. In due ore lo hai fatto e finito, con test allegati. Con le  
API C di Python, beh, prima devi imparare un po' come funzionano. Non  
che sia veramente complesso, ma forse sempre più rognoso di quello che  
vuoi fare.








Maggiori informazioni sulla lista Python