Qual'è la differenza tra encode / decode?


180

Non sono mai stato sicuro di aver compreso la differenza tra decodifica / codifica str / unicode.

So che str().decode()è per quando hai una stringa di byte che sai che ha una certa codifica dei caratteri, dato che il nome della codifica restituirà una stringa unicode.

So che unicode().encode()converte i caratteri unicode in una stringa di byte in base a un determinato nome di codifica.

Ma non capisco cosa str().encode()e unicode().decode()per cosa. Qualcuno può spiegare, e forse anche correggere qualcos'altro che ho sbagliato sopra?

MODIFICARE:

Diverse risposte forniscono informazioni su cosa .encodefa una stringa, ma nessuno sembra sapere cosa .decodefa per unicode.


Penso che la seconda risposta di questa pagina sia abbastanza chiara e concisa.
Ben

Risposte:


106

Il decodemetodo delle stringhe unicode in realtà non ha alcuna applicazione (a meno che tu non abbia alcuni dati non testuali in una stringa unicode per qualche motivo - vedi sotto). È principalmente lì per motivi storici, penso. In Python 3 è completamente sparito.

unicode().decode()eseguirà un implicito codifica di sutilizzare il (ASCII) codec predefinito. Verifica in questo modo:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

>>> s.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

I messaggi di errore sono esattamente gli stessi.

Per str().encode()è il contrario - tenta un implicito decodifica di scon la codifica predefinita:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
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)

Usato in questo modo, str().encode()è anche superfluo.

Ma c'è un'altra applicazione di quest'ultimo metodo che è utile: ci sono codifiche che non hanno nulla a che fare con i set di caratteri, e quindi possono essere applicate alle stringhe a 8 bit in modo significativo:

>>> s.encode('zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

Hai ragione, però: l'uso ambiguo della "codifica" per entrambe queste applicazioni è ... imbarazzante. Ancora una volta, con separati bytee stringtipi in Python 3, questo non è più un problema.


4
.decode()sulle stringhe Unicode potrebbe essere utile, ad esempio,print u'\\u0203'.decode('unicode-escape')
jfs

Buon esempio @JFSebastian in python3 Immagino che faresti:print u'\\u0203'.encode('utf8').decode('unicode-escape')
AJP

1
@AJP: su Python 3:codecs.decode(u'\\u0203', 'unicode-escape')
jfs il

@hop: si. Per rilevare input non validi e per la compatibilità con Python 2/3, la stringa può essere codificata esplicitamente usando la asciicodifica:\\u0203\u00e4'.encode('ascii').decode('unicode-escape')
jfs

@hop: il tuo primo commento (perché l'hai eliminato? Non eliminare i commenti a cui è stato risposto) lo ha già detto. La mia risposta ( .encode('ascii').decode('unicode-escape')) non dipende da sys.getdefaultencoding().
jfs,

71

Per rappresentare una stringa unicode come una stringa di byte è noto come codifica . Usa u'...'.encode(encoding).

Esempio:

    >>> u'æøå'.encode ('utf8')
    '\ Xc3 \ x83 \ xc2 \ xa6 \ xc3 \ x83 \ xc2 \ XB8 \ xc3 \ x83 \ xc2 \ xa5'
    >>> u'æøå'.encode ('latin1')
    '\ Xc3 \ xa6 \ xc3 \ XB8 \ xc3 \ xa5'
    >>> u'æøå'.encode ('ascii')
    UnicodeEncodeError: il codec 'ascii' non può codificare i caratteri nella posizione 0-5: 
    ordinale non nel range (128)

In genere si codifica una stringa unicode ogni volta che è necessario utilizzarla per IO, ad esempio trasferirla sulla rete o salvarla su un file su disco.

Per convertire una stringa di byte in una stringa unicode è noto come decodifica . Utilizzare unicode('...', encoding)o '...'. Decodifica (codifica).

Esempio:

   >>> u'æøå '
   u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5' # l'interprete stampa l'oggetto unicode in questo modo
   >>> unicode ('\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5', 'latin1')
   u '\ xc3 \ xa6 \ xc3 \ XB8 \ xc3 \ xa5'
   >>> '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'.decode (' latin1 ')
   u '\ xc3 \ xa6 \ xc3 \ XB8 \ xc3 \ xa5'

In genere si decodifica una stringa di byte ogni volta che si ricevono dati di stringa dalla rete o da un file su disco.

Credo che ci siano alcuni cambiamenti nella gestione degli Unicode in Python 3, quindi quanto sopra probabilmente non è corretto per Python 3.

Alcuni buoni collegamenti:


6
Non hai risposto alla domanda del PO. OP vuole sapere cosa fanno str.encode () e unicode.decode (). Hai appena ripetuto quanto affermato nella domanda originale.
stuckintheshuck

Ottima risposta al motivo per cui in pratica avresti mai pasticciato con la decodifica e la codifica. Non tutte le macchine comprendono lo stesso set di caratteri, ma tutti comprendono i byte. Codifica in byte per una lingua che i computer comprendono universalmente (e possono essere trasferiti o salvati su disco), ma decodifica quando gli umani devono effettivamente leggere quei byte (ad es. Sul lato client).
Alex Petralia,

Risposta fantastica! Questo dovrebbe salire !!
sandyp,

16

anUnicode. encode ('encoding') genera un oggetto stringa e può essere chiamato su un oggetto unicode

una stringa. decodifica ('codifica') genera un oggetto unicode e può essere chiamato su una stringa, codificato in una data codifica.


Qualche spiegazione in più:

Puoi creare un oggetto unicode, che non ha alcun set di codifica. Il modo in cui è memorizzato da Python in memoria non è un problema. Puoi cercarlo, dividerlo e chiamare qualsiasi funzione di manipolazione delle stringhe che ti piace.

Ma arriva un momento in cui desideri stampare l'oggetto unicode sulla console o in un file di testo. Quindi devi codificarlo (per esempio - in UTF-8), chiami encode ('utf-8') e ottieni una stringa con '\ u <someNumber>', che è perfettamente stampabile.

Quindi, ancora una volta - ti piacerebbe fare il contrario - leggi la stringa codificata in UTF-8 e la tratti come un Unicode, quindi \ u360 sarebbe un carattere, non 5. Quindi decodifichi una stringa (con la codifica selezionata) e ottenere un oggetto nuovissimo del tipo unicode.

Proprio come una nota a margine: puoi selezionare alcune codifiche pervertite, come 'zip', 'base64', 'rot' e alcune di esse si convertiranno da una stringa all'altra, ma credo che il caso più comune sia quello che coinvolge UTF-8 / UTF-16 e stringa.


12

mybytestring.encode (somecodec) è significativo per questi valori di somecodec:

  • Base64
  • bz2
  • zlib
  • esadecimale
  • quopri
  • rot13
  • string_escape
  • uu

Non sono sicuro di cosa sia utile decodificare un testo Unicode già decodificato. Provare che con qualsiasi codifica sembra provare sempre a codificare prima con la codifica predefinita del sistema.


5

Ci sono alcune codifiche che possono essere usate per de- / codificare da str a str o da unicode a unicode. Ad esempio base64, hex o persino rot13. Sono elencati nel modulo codec .

Modificare:

Il messaggio di decodifica su una stringa unicode può annullare l'operazione di codifica corrispondente:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

Il tipo restituito è str invece di unicode che è sfortunato a mio avviso. Ma quando non stai eseguendo una corretta en / decodifica tra str e unicode, questo sembra comunque un casino.


1
-1: il metodo di decodifica non viene applicato all'oggetto unicode. Invece, l'oggetto unicode viene codificato come bytestring "ascii", prima che inizi l'operazione di decodifica. Per una prova di tale affermazione, prova u'ã'.decode ('hex') - che produce UnicodeEncodeError
nosklo

2
@nosklo: hai ragione. Quello che intendevo davvero è che gli oggetti unicode hanno un metodo decode () in modo da poter applicare anche a loro codec codifica non di caratteri. Tutta questa attività di codifica non basata sui caratteri rende questa interfaccia un casino in Python <3.

1

La semplice risposta è che sono l'esatto opposto l'uno dell'altro.

Il computer utilizza l'unità base di byte per memorizzare ed elaborare le informazioni; non ha senso per gli occhi umani.

Ad esempio, "\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87" è la rappresentazione di due caratteri cinesi, ma il computer sa solo (che significa stampa o archivio) che sono i caratteri cinesi quando gli viene dato un dizionario per cercarlo Parola cinese, in questo caso, è un dizionario "utf-8" e non riuscirebbe a mostrare correttamente la parola cinese desiderata se si guardasse in un dizionario diverso o sbagliato (usando un metodo di decodifica diverso).

Nel caso sopra, il processo per un computer per cercare la parola cinese è decode().

E il processo di scrittura del computer cinese nella memoria del computer è encode().

Quindi le informazioni codificate sono i byte grezzi e le informazioni decodificate sono i byte grezzi e il nome del dizionario a cui fare riferimento (ma non il dizionario stesso).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.