[Python] Che barba sta codifica!
Marco Buttu
marco.buttu a gmail.com
Sab 20 Giu 2015 09:39:57 CEST
On 19/06/2015 17:56, Manlio Perillo wrote:
> 2015-06-19 16:58 GMT+02:00 Diego Barrera <diegonebarrera a yahoo.it
> <mailto:diegonebarrera a yahoo.it>>:
>
> premesso che non ho mai capito come funziona la codifica dei
> caratteri,
>
>
> Documentati il prima possibile.
> Ad esempio:
> http://www.joelonsoftware.com/articles/Unicode.html
Ascolta il suggerimento di Manlio ;)
La codifica dei caratteri e' il pane quotidiano di un programmatore, per
cui se non si capisce come funziona, prima di andare avanti ci si deve
soffermare (un pomeriggio, due, quanto basta) per studiarla e capirla
*sino in fondo*. E' veramente un concetto imprescindibile. La
distinzione tra testo e byte che si ha in Python 3 viene spesso
criticata, ma credo sia uno dei suoi maggiori punti di forza, ed è una
scelta veramente Pythonica, in perfetto accordo con lo Zen di Python.
In Python 2 poi darmi una sequenza di byte come stringa:
>>> open('myfile', 'w').write('via 1\xf8 Maggio, 21') # Python 2
e io posso leggerla come testo, senza pormi alcun problema:
>>> open('myfile').read() # Python 2
'via 1\xf8 Maggio, 21'
Questo non solleva eccezioni, e per chi non sa cosa sta sotto il
passaggio da byte a testo (che qua non avviene, perche' in Python 2 e'
un miscuglio) e viceversa, e' il comportamento desiderato, visto che "Il
mio programma gira, anche se ogni tanto mi saltano fuori caratteri
strani". E infatti anche per questo abbiamo mojibake dietro ogni angolo.
In Python 3 la musica cambia. *Giustamente* i byte sono byte, e il testo
e' testo, ovvero una sequenza di byte interpretata secondo una data
codifica. Apro il file in lettura, e per default open() tira fuori il
_testo_. Ma per poter ottenere testo da quella sequenza di byte,
ovviamente deve poter sapere come interpretare tali byte. Per default
ipotizza che voglio usare l'encoding impostato nella mia macchina (utf-8):
>>> open('myfile').read()
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf8...
Non e' utf-8. Se so cosa fare, lo faccio:
>>> open('myfile', encoding='cp850').read() # Grazie a Carlo ;)
'via 1° Maggio, 21'
Se non ho idea di come il testo originale e' stato codificato, e non
voglio provare ad indovinare, posso *esplicitamente* indicare di fare
passare gli errori silenziosamente:
>>> open('myfile', errors='ignore').read()
'via 1 Maggio, 21'
"Explicit is better than implicit" and "Errors should never pass silently".
Morale della favola:
* impensabile non spendere qualche pomeriggio per studiare la codifica
dei caratteri
* byte e testo non sono la stessa cosa
* Python 3 ha scelto la soluzione piu' pythonica per gestire la cosa
--
Marco Buttu
INAF-Osservatorio Astronomico di Cagliari
Via della Scienza n. 5, 09047 Selargius (CA)
Phone: 070 711 80 217
Email: mbuttu a oa-cagliari.inaf.it
Maggiori informazioni sulla lista
Python