2010-07-03 16 views
98

Sto ancora imparando Python e ho un dubbio:Perché dichiarare unicode per stringa in python?

in Python 2.6.x solito dichiarare la codifica nell'intestazione del file di questo tipo (come in PEP 0263)

# -*- coding: utf-8 -*- 

Dopo di che, le mie corde sono scritti come al solito:

a = "A normal string without declared Unicode" 

Ma ogni volta che vedo un codice di progetto di pitone, la codifica non è dichiarato al l'intestazione. Invece, è dichiarato in ogni stringa come questa:

a = u"A string with declared Unicode" 

Qual è la differenza? Qual è lo scopo di questo? So che Python 2.6.x imposta la codifica ASCII per impostazione predefinita, ma può essere sostituita dalla dichiarazione dell'intestazione, quindi qual è il punto della dichiarazione per stringa?

Addendum: Sembra che io abbia confuso codifica dei file con la codifica della stringa. Grazie per averlo spiegato :)

+4

'# codifica: utf8' è abbastanza buono, non c'è bisogno per' - * - ' – jellyfish

+0

@jellyfish presumo si intende digitare' # codifica: utf -8'. –

+0

Dovrebbe essere '# coding = utf-8'. https://www.python.org/dev/peps/pep-0263/ –

risposta

141

Queste sono due cose diverse, come altri hanno detto.

Quando si specifica # -*- coding: utf-8 -*-, stai dicendo Python il file di origine che hai salvato è utf-8. L'impostazione predefinita per Python 2 è ASCII (per Python 3 è utf-8). Questo influenza solo il modo in cui l'interprete legge i caratteri nel file.

In generale, probabilmente non è la migliore idea incorporare caratteri unicode alti nel file, indipendentemente dalla codifica; puoi usare gli escape unicode delle stringhe, che funzionano in entrambe le codifiche.


Quando si dichiara una stringa con un u davanti, come u'This is a string', racconta il compilatore Python che la stringa è Unicode, non byte. Questo è gestito per lo più in modo trasparente dall'interprete; la differenza più ovvia è che ora è possibile incorporare caratteri unicode nella stringa (ovvero, u'\u2665' è legale). È possibile utilizzare from __future__ import unicode_literals per impostarlo come predefinito.

Questo si applica solo a Python 2; in Python 3 l'impostazione predefinita è Unicode e devi specificare un davanti (come b'These are bytes', per dichiarare una sequenza di byte).

+0

Grazie per la spiegazione! Imposterò questo come accettato poiché è il più completo :) –

+2

La codifica sorgente predefinita per Python 2 è ** ascii **. –

+23

In realtà è una buona idea incorporare caratteri unicode alti nel tuo file. Dubito che i parlanti non anglofoni vogliano leggere le fughe di unicode nelle loro stringhe. –

10

Che non imposta il formato della stringa; imposta il formato del file. Anche con quell'intestazione, "hello" è una stringa di byte, non una stringa Unicode. Per renderlo Unicode, dovrai usare u"hello" ovunque. L'intestazione è solo un suggerimento su quale formato utilizzare durante la lettura del file .py.

+0

Mi sono sbagliato, ho pensato che fossero uguali. Quindi l'uso delle stringhe unicode è i18n? –

+0

@Oscar: Sì, per la maggior parte. Se stavi creando un sito Web con Django o qualcosa del genere e dovessi gestire persone con caratteri non ASCII, questo è un altro possibile utilizzo. – icktoofay

7

La definizione dell'intestazione consiste nel definire la codifica del codice stesso, non le stringhe risultanti in fase di esecuzione.

mettere un carattere non ASCII, come 2 nello script python, senza la definizione di intestazione utf-8 sarà lanciare un avvertimento error http://www.freeimagehosting.net/uploads/1ed15124c4.jpg

+0

Errore errato, ma si. –

+0

oops, corretto grazie – ebt

19

Come altri hanno già detto, # coding: specifica la codifica in cui è salvato il file di origine.Ecco alcuni esempi per illustrare questo:

un file salvato sul disco come CP437 (la mia codifica console), ma nessuna codifica dichiarato

b = 'über' 
u = u'über' 
print b,repr(b) 
print u,repr(u) 

uscita:

File "C:\ex.py", line 1 
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no 
encoding declared; see http://www.python.org/peps/pep-0263.html for details 

Uscita del file con # coding: cp437 aggiunto:

über '\x81ber' 
über u'\xfcber' 

Inizialmente, Python non conosceva la codifica e si lamentava del carattere non ASCII. Una volta che conosceva la codifica, la stringa di byte otteneva i byte che erano effettivamente sul disco. Per la stringa Unicode, Python leggeva \ x81, sapeva che in cp437 era ü e lo decodifica nel punto di codice Unicode per ü che è U + 00FC. Quando la stringa di byte è stata stampata, Python ha inviato direttamente il valore esadecimale 81 alla console. Quando è stata stampata la stringa Unicode, Python ha rilevato correttamente la codifica della console come cp437 e tradotto Unicode ü nel valore cp437 per ü.

Ecco cosa succede con un file dichiarata e salvato in UTF-8:

├╝ber '\xc3\xbcber' 
über u'\xfcber' 

In UTF-8, ü è codificato come l'esagono byte C3 BC, quindi la stringa di byte contiene quei byte , ma la stringa Unicode è identica al primo esempio. Python legge i due byte e decodifica correttamente. Python ha stampato la stringa di byte in modo errato, perché ha inviato i due byte UTF-8 che rappresentano ü direttamente alla mia console cp437.

Ecco il file viene dichiarato CP437, ma salvato in UTF-8:

├╝ber '\xc3\xbcber' 
├╝ber u'\u251c\u255dber' 

La stringa di byte ancora ottenuto i byte su disco (UTF-8 esadecimale byte C3 BC), ma li interpretato come due caratteri cp437 invece di un singolo carattere con codifica UTF-8. Questi due caratteri vengono convertiti in punti codice Unicode e tutto viene stampato in modo errato.

+0

+1 per gli esempi :) –

0

se si utilizza python 2, aggiungere questo: from __future__ import unicode_literals

Problemi correlati