Python Language
Unicode und Bytes
Suche…
Syntax
- str.encode (Kodierung, Fehler = 'streng')
- bytes.decode (Kodierung, Fehler = 'streng')
- offen (Dateiname, Modus, Kodierung = Keine)
Parameter
Parameter | Einzelheiten |
---|---|
Codierung | Die zu verwendende Kodierung, zB 'ascii' , 'utf8' usw. |
Fehler | Der Fehlermodus, z. B. 'replace' , um ungültige Zeichen durch Fragezeichen zu ersetzen, 'ignore' , um ungültige Zeichen zu ignorieren usw. |
Grundlagen
In Python 3 ist str
der Typ für Unicode-aktivierte Zeichenfolgen, während bytes
der Typ für Sequenzen von unformatierten Bytes ist.
type("f") == type(u"f") # True, <class 'str'>
type(b"f") # <class 'bytes'>
In Python 2 war eine zufällige Zeichenfolge standardmäßig eine Folge roher Bytes, und die Unicode-Zeichenfolge bestand aus jeder Zeichenfolge mit dem Präfix "u".
type("f") == type(b"f") # True, <type 'str'>
type(u"f") # <type 'unicode'>
Unicode in Bytes
Unicode-Zeichenfolgen können mit .encode(encoding)
in Bytes konvertiert werden.
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 lautet die Standardkonsolencodierung sys.getdefaultencoding() == 'ascii'
und nicht utf-8
wie in py3. Daher ist das Drucken wie in dem vorherigen Beispiel nicht direkt möglich.
>>> 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
Wenn die Codierung die Zeichenfolge nicht verarbeiten kann, wird ein UnicodeEncodeError-Fehler ausgelöst:
>>> "£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)
Bytes bis Unicode
Bytes können mit .decode(encoding)
in Unicode-Zeichenfolgen .decode(encoding)
.
Eine Folge von Bytes kann nur mit der entsprechenden Kodierung in einen Unicode-String umgewandelt werden!
>>> b'\xc2\xa313.55'.decode('utf8')
'£13.55'
Wenn die Codierung die Zeichenfolge nicht verarbeiten kann, wird ein 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
Behandlung von Codierungs- / Decodierungsfehlern
.encode
und .decode
beide .decode
.
Der Standardwert ist 'strict'
, was bei Fehlern zu Ausnahmen führt. Andere Modi sind verzeihender.
Codierung
>>> "£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'
Dekodierung
>>> 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'
Moral
Aus dem Vorstehenden ist klar, dass es wichtig ist, Ihre Kodierungen beim Umgang mit Unicode und Bytes gerade zu halten.
Datei I / O
Dateien, die in einem nicht binären Modus geöffnet wurden (z. B. 'r'
oder 'w'
), behandeln Strings. Die Deafult-Kodierung lautet '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")
Dateien, die in einem binären Modus geöffnet werden (z. B. 'rb'
oder 'wb'
), behandeln Bytes. Es kann kein Kodierungsargument angegeben werden, da keine Kodierung vorhanden ist.
open(fn, mode='wb') # open file for writing bytes
# ERROR: cannot write string when bytes is expected:
open(fn, mode='wb').write("hi")