Python Language
Unicode e byte
Ricerca…
Sintassi
- str.encode (encoding, errors = 'strict')
- bytes.decode (encoding, errors = 'strict')
- open (nomefile, modo, codifica = Nessuno)
Parametri
Parametro | Dettagli |
---|---|
codifica | La codifica da usare, ad esempio 'ascii' , 'utf8' , ecc ... |
errori | La modalità errori, ad esempio 'replace' per sostituire i caratteri non validi con punti interrogativi, 'ignore' per ignorare i caratteri errati, ecc ... |
Nozioni di base
In Python 3 str
è il tipo per le stringhe abilitate per Unicode, mentre i bytes
è il tipo per le sequenze di byte non elaborati.
type("f") == type(u"f") # True, <class 'str'>
type(b"f") # <class 'bytes'>
In Python 2 una stringa casuale era una sequenza di byte grezzi per impostazione predefinita e la stringa unicode era ogni stringa con prefisso "u".
type("f") == type(b"f") # True, <type 'str'>
type(u"f") # <type 'unicode'>
Unicode in byte
Le stringhe Unicode possono essere convertite in byte con .encode(encoding)
.
Python 3
>>> "£13.55".encode('utf8')
b'\xc2\xa313.55'
>>> "£13.55".encode('utf16')
b'\xff\xfe\xa3\x001\x003\x00.\x005\x005\x00'
Python 2
in py2 la codifica della console predefinita è sys.getdefaultencoding() == 'ascii'
e non utf-8
come in py3, quindi la stampa come nell'esempio precedente non è direttamente possibile.
>>> print type(u"£13.55".encode('utf8'))
<type 'str'>
>>> print u"£13.55".encode('utf8')
SyntaxError: Non-ASCII character '\xc2' in...
# with encoding set inside a file
# -*- coding: utf-8 -*-
>>> print u"£13.55".encode('utf8')
£13.55
Se la codifica non può gestire la stringa, viene sollevato un `UnicodeEncodeError`:
>>> "£13.55".encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xa3' in position 0: ordinal not in range(128)
Byte per unicode
I byte possono essere convertiti in stringhe unicode con .decode(encoding)
.
Una sequenza di byte può essere convertita in una stringa unicode solo tramite la codifica appropriata!
>>> b'\xc2\xa313.55'.decode('utf8')
'£13.55'
Se la codifica non è in grado di gestire la stringa, viene generato un UnicodeDecodeError
:
>>> b'\xc2\xa313.55'.decode('utf16')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/csaftoiu/csaftoiu-github/yahoo-groups-backup/.virtualenv/bin/../lib/python3.5/encodings/utf_16.py", line 16, in decode
return codecs.utf_16_decode(input, errors, True)
UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x35 in position 6: truncated data
Gestione degli errori di codifica / decodifica
.encode
e .decode
hanno entrambi modalità di errore.
L'impostazione predefinita è 'strict'
, che solleva eccezioni in caso di errore. Altre modalità sono più indulgenti.
Codifica
>>> "£13.55".encode('ascii', errors='replace')
b'?13.55'
>>> "£13.55".encode('ascii', errors='ignore')
b'13.55'
>>> "£13.55".encode('ascii', errors='namereplace')
b'\\N{POUND SIGN}13.55'
>>> "£13.55".encode('ascii', errors='xmlcharrefreplace')
b'£13.55'
>>> "£13.55".encode('ascii', errors='backslashreplace')
b'\\xa313.55'
decodifica
>>> b = "£13.55".encode('utf8')
>>> b.decode('ascii', errors='replace')
'��13.55'
>>> b.decode('ascii', errors='ignore')
'13.55'
>>> b.decode('ascii', errors='backslashreplace')
'\\xc2\\xa313.55'
Morale
Da quanto sopra è chiaro che è fondamentale mantenere le codifiche corrette quando si ha a che fare con unicode e byte.
File I / O
I file aperti in modalità non binaria (es. 'r'
o 'w'
) gestiscono le stringhe. La codifica sorda è 'utf8'
.
open(fn, mode='r') # opens file for reading in utf8
open(fn, mode='r', encoding='utf16') # opens file for reading utf16
# ERROR: cannot write bytes when a string is expected:
open("foo.txt", "w").write(b"foo")
I file aperti in modalità binaria (ad esempio 'rb'
o 'wb'
) gestiscono i byte. Nessun argomento di codifica può essere specificato in quanto non esiste alcuna codifica.
open(fn, mode='wb') # open file for writing bytes
# ERROR: cannot write string when bytes is expected:
open(fn, mode='wb').write("hi")