|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2007
Messaggi: 316
|
[Python] Encoding di una stringa letta da file
Ciao a tutti,
mi sto avvicinando pian piano a Python facendo vari script e test; sono su windows e uso SPE. Stavo testando un po' la lettura da file e la successiva elaborazione delle stringhe ottenute, ma ho un problema con l'encoding. Per maggior chiarezza posto il (poco) codice e l'output che vorrei encodare/decodare (ancora non l'ho capito) Codice:
import os.path
f = open("C:\\inferno.txt","r")
print f.encoding # risulta none
canti = [[] for i in range(100)] #forse questa è inutile ma vabbè
i = 0
for line in f.readlines():
if line.find("CANTO") != -1:
i = i + 1
canti[i].append(line)
line.encode("ascii")
print canti[3]
f.close()
Codice:
['CANTO III\n', "[Canto terzo, nel quale tratta de la porta e de l'entrata de l'inferno e del fiume d'Acheronte, de la pena di coloro che vissero sanza opere di fama degne, e come il demonio Caron li trae in sua nave e come elli parl\xc3\xb2 a l'auttore; e tocca qui questo vizio ne la persona di papa Cilestino.]\n", "'Per me si va ne la citt\xc3\xa0 dolente,\n", ...... Il problema sono le lettere strane/accentate che non capisco come debbano essere trattate Ho tentato con un line.encode('utf_8') ma ottengo questo errore: Codice:
line.encode("utf_8")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 138: ordinal not in range(128)
Grazie in anticipo |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Prova ad usare canti[i].append(unicode(line)), anche se non sono sicuro che faccia al caso tuo.
ciao
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Sep 2007
Messaggi: 316
|
Quote:
purtroppo mi da lo stesso errore Codice:
canti[i].append(unicode(line)) UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 138: ordinal not in range(128) |
|
|
|
|
|
|
#4 | |
|
Member
Iscritto dal: Nov 2007
Messaggi: 88
|
Quote:
Codice:
line.encode('latin-1')
|
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Sep 2007
Messaggi: 316
|
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
utf_16 ?
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Python ha due tipi di stringhe (tranne con la versione 3.0, ma per il momento non ne parliamo): sequenze di byte e unicode. Nel primo caso possiamo manipolare "buffer" senza occuparci della codifica: sono byte "grezzi". Nel secondo caso gli unici caratteri supportati sono quelli che hanno una codifica Unicode corretta. Fortunatamente in Python il problema della codifica e decodifica è stato risolto molto bene grazie a un sistema di codec da e verso i quali è possibile effettuate le conversioni. Vi risparmio la teoria e passiamo subito alla pratica col caso sollevato qui, in modo da capire immediatamente come sfruttare questi strumenti. Innanzitutto bisogna capire bene qual è la codifica del file letto. Dall'output incollato: Codice:
"[Canto terzo, nel quale tratta de la porta e de l'entrata de l'inferno e del fiume d'Acheronte, de la pena di coloro che vissero sanza opere di fama degne, e come il demonio Caron li trae in sua nave e come elli parl\xc3\xb2 a l'auttore; e tocca qui questo vizio ne la persona di papa Cilestino.]\n" Questo significa che se prendo la stringa così com'è e la stampo a video, ottengo dei caratteri strani a video, perché Python di default imposta la codifica di sistema. Quindi se prendo quella stringa e la codifica di default è latin1, eseguendo un print mi aspetto che i byte C3 e B2 in esadecimale rappresentino dei validi caratteri latin1, cp1252 o altro (a seconda del codepage impostato). Questo non è vero, perché, appunto si tratta di una codifica utf8. Cosa dobbiamo fare quindi per poter stampare correttamente quei dati? Bisogna convertire lo stream di byte utf8 in una stringa unicode, e questo lo si fa col metodo decode della stringhe, specificando qual è l'encoding dello stream che si vuole convertire: Codice:
s.decode('utf-8')
In questo modo otteniamo una stringa unicode, che Python può gestire tranquillamente a seconda della codifica di default impostata nel sistema. Questo significa che se cercate di stamparla Python provvederà automaticamente a effettuare le opportune conversioni per ottenere un output corretto. A parte questo se, ad esempio, volessimo ricodificare la stringa in latin1, ad esempio, l'operazione da fare è semplicissima: Codice:
u.encode('latin1')
Dopo quest'operazione, se tutto va bene (spiego dopo il perché), siamo sicuri che lo stream di byte ottenuto sia codificato in latin1. Dicevo prima se tutto va bene, perché non è detto che una codifica (ma anche una decodifica) possa essere eseguita correttamente. Basti provare a convertire la stringa di cui sopra in ascii, ad esempio: Codice:
>>> print s.decode('utf-8').encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf2' in position 216: ordinal not in range(128)
In questi casi Python prevede il sollevamento di un'eccezione, ma è possibile modificarne il comportamento (ad esempio ignorando o rimpiazzando i caratteri non codificabili) specificando cosa fare col secondo parametro (opzionale) di encode o decode. E' tutto. Se ci sono dubbi chiedete pure.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys Ultima modifica di cdimauro : 14-12-2008 alle 08:52. |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Figurati: è un piacere dare una mano, quando posso.
Quel link l'avevo letto tempo fa ed è proprio quello che mi ha illuminato sulla questione.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:48.





















