[Python] Usare Unicode e charset
Manlio Perillo
manlio_perillo a libero.it
Mer 2 Dic 2009 18:32:03 CET
Massimo Capanni ha scritto:
> Salve,
>
> confesso che ho un po' di timore a postare questo thread,
e perchè mai?
> per il fatto che sono tre giorni che cerco di capire questo argomento
> e ad ogni articolo che studio in merito mi sembra di fare un passo indietro
> su quello che ho imparato.
>
> Comunque, ecco la mia situazione: Windows Xp e Python 2.4.6
> Tutto e' cominciato ignorando (mea culpa) questo problema:
>
> Listato [1]
> ---------------------------------
> file = open("prova.txt", "w")
> x = 'àòàòàòàò'
Qui probabilmente dovresti usare una stringa Unicode:
x = u'àòàòàòàò'
> file.write(x)
file.write(x.encode('the_encoding_of_your_choice'))
> file.close()
> ---------------------------------
>
> e il prompt dei comandi mi risponde con:
>
> ----------------------------------------
> C:\_DATI\pylab>python prova.py
> File "prova.py", line 2
> SyntaxError: Non-ASCII character '\xe0' in file prova.py on line 2, but no
> encoding declared; see http://www.python.org/peps/pep-0263.html for
> details
> ----------------------------------------
>
> Visto che l'interprete mi consiglia di leggere il link relativo nel messaggio
> di errore gli do un'occhiata e provo ad aggiungere :
>
> # -*- coding: utf-8 -*-
>
Attenzione che non puoi mettere un encoding a caso.
Deve essere l'encoding effettivamente utilizzato nel file.
Cosa hai usato per editare il file?
Alcuni editor riconoscono quella dichiarazione, e salvano il file usando
l'encoding specificato.
> e tutto funziona.
>
> Se invece da shell Python scrivo:
>
> Listato [2]
> ---------------------------------
>>>> x = "ààòàò"
>>>> print x
> ààòàò
>>>> f = open("pippo.txt", "w")
>>>> f.write(x)
>>>> f.close()
> ---------------------------------
>
> leggendo il file pippo.txt l'output mi stampa:
>
>> ààòàò
>
> E qui inziano i miei dubbi.
>
La shell si comporta in modo diverso.
Infatti, a differenza di quando esegui il codice Python in un file
(modalità batch), in questo caso Python **sa** l'encoding che stai
usando, perchè lo riporta il sistema operativo.
> Anzitutto a quanto ho capito dalla documentazione in giro, Python di
> default utilizza il charset 'ascii', infatti se eseguo queste due istruzioni
> dalla shell ottengo:
>
>>>> import sys
>>>> sys.getdefaultencoding()
> 'ascii'
>
Ci sono due informazioni in cui Python ha bisogno di conoscere
l'encoding usato.
Il primo caso è quando, nel listato del programma, hai una string literal.
In questo caso l'encoding è necessario in fase di parsing del programma.
Nel caso in cui l'interprete è eseguito in modalità interattiva, questa
informazione viene ricavata dal sistema operativo.
In modalità batch questa informazione deve essere dichiarata dal
programmatore nel file che contiene il programma.
Il secondo caso è quando converti una stringa normale in Unicode.
>>> byte_string = 'àè'
>>> s = unicode(byte_string)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf-8')
>>> s = unicode(byte_string)
>>>
Nel mio caso, sono su Linux ed ho il locale impostato a `it_IT.utf8`.
Ci possono essere altri casi; dovrei controllare i sorgenti per
verificare che quanto ho scritto è corretto al 100%.
> [...]
> Provo a fare delle ipotesi:
>
> ho tre soggetti: il sistema sul quale lavoro, l'editor, Python. Il
> sistema possiede il
> suo charset (ad esempio la cmd di windows mi riporta 437).
Ti conviene utilizzare un altro encoding;
come fare viene spiegato qui:
http://www.postgresql.org/docs/8.4/static/app-psql.html#AEN71654
> [...]
Ciao Manlio
Maggiori informazioni sulla lista
Python