2012-01-15 17 views
6

Si consideri il seguente esempio:codifica utilizzata per u "" letterali

>>> s = u"баба" 
>>> s 
u'\xe1\xe0\xe1\xe0' 
>>> print s 
áàáà 

sto usando cp1251 codifica all'interno di inattività, ma sembra l'interprete utilizza effettivamente latin1 per creare stringhe Unicode:

>>> print s.encode('latin1') 
баба 

Perché così? C'è una specifica per un simile comportamento?

CPython, 2.7.


Modifica

Il codice che è stato effettivamente cercando è

>>> u'\xe1\xe0\xe1\xe0' == u'\u00e1\u00e0\u00e1\u00e0' 
True 

Sembra come durante la codifica unicode con latin1 codec, tutti i punti unicode meno che 256 sono semplicemente lasciato come è quindi risultando in byte che ho digitato prima.

+3

stai chiedendo la domanda sbagliata. La domanda non è "quale codifica viene utilizzata per i letterali stringa Unicode" (una domanda priva di significato, le codifiche sono elementi di input/output, la rappresentazione interna è ovviamente qualcosa che può rappresentare Unicode e questo è tutto ciò che devi sapere). La domanda a cui vuoi veramente rispondere è "perché IDLE sta rovinando le mie codifiche di testo, e sta accadendo su input o output, e come faccio a fare ciò che voglio?" – kindall

+3

Come stai definendo la tua codifica? vedere http://www.python.org/dev/peps/pep-0263/ per definire la codifica nel file sorgente. Per favore, dai anche la tua versione di Python. Secondo http://docs.python.org/howto/unicode.html la codifica predefinita utilizzata sarà ASCII. Le versioni di Python precedenti alla 2.4 erano eurocentriche e assumevano Latin-1 come codifica predefinita per le stringhe letterali –

+0

@kindall beh, afaik, abbiamo bisogno di avere la codifica durante la creazione di un oggetto unicode (poiché non abbiamo bisogno di byte, ma di caratteri significativi) . Allora perché l'interprete non usa la mia vera codifica per eseguire bytes-> caratteri trans? –

risposta

8

Quando si digita un carattere come б nel terminale, viene visualizzato uno б, ma ciò che viene realmente immesso è una sequenza di byte.

Poiché la codifica terminale è cp1251, digitando баба risultati nella sequenza di byte pari al unicode баба codificato in cp1251:

In [219]: "баба".decode('utf-8').encode('cp1251') 
Out[219]: '\xe1\xe0\xe1\xe0' 

(Nota uso utf-8 sopra perché la mia codifica terminale è utf-8, non cp1251 Per me, "баба".decode('utf-8') è unicode per баба.)

Poiché digitare баба genera la sequenza di byte s \xe1\xe0\xe1\xe0, quando si digita u"баба" nel terminale, Python riceve invece u'\xe1\xe0\xe1\xe0'. Questo è il motivo per cui si sta vedendo

>>> s 
u'\xe1\xe0\xe1\xe0' 

Ciò accade unicode per rappresentare áàáà.

E quando si digita

>>> print s.encode('latin1') 

la codifica latin1 converte u'\xe1\xe0\xe1\xe0'-'\xe1\xe0\xe1\xe0'. Il terminale riceve la sequenza di byte '\xe1\xe0\xe1\xe0', e li decodifica con cp1251, stampando così баба:

In [222]: print('\xe1\xe0\xe1\xe0'.decode('cp1251')) 
баба 

Prova:

>>> s = "баба" 

(senza u) invece. Oppure,

>>> s = "баба".decode('cp1251') 

per fare sunicode.In alternativa, utilizzare il verbose ma molto esplicita (e terminale-codifica agnostico):

>>> s = u'\N{CYRILLIC SMALL LETTER BE}\N{CYRILLIC SMALL LETTER A}\N{CYRILLIC SMALL LETTER BE}\N{CYRILLIC SMALL LETTER A}' 

O il breve ma meno facilmente comprensibile

>>> s = u'\u0431\u0430\u0431\u0430' 
+0

grazie, mi hai tirato nel modo giusto. –

Problemi correlati