Python Language
Unicode en bytes
Zoeken…
Syntaxis
- str.encode (codering, fouten = 'streng')
- bytes.decode (codering, fouten = 'streng')
- open (bestandsnaam, modus, codering = Geen)
parameters
Parameter | Details |
---|---|
codering | De te gebruiken codering, bijvoorbeeld 'ascii' , 'utf8' , enz ... |
fouten | De foutmodus, bijvoorbeeld 'replace' om slechte tekens te vervangen door vraagtekens, 'ignore' om slechte tekens te negeren, enz ... |
Basics
In Python is 3 str
het type voor tekenreeksen waarvoor Unicode is ingeschakeld, terwijl bytes
het type is voor reeksen onbewerkte bytes.
type("f") == type(u"f") # True, <class 'str'>
type(b"f") # <class 'bytes'>
In Python 2 was een losse string standaard een reeks onbewerkte bytes en de unicode-string was elke string met "u" -voorvoegsel.
type("f") == type(b"f") # True, <type 'str'>
type(u"f") # <type 'unicode'>
Unicode naar bytes
Unicode-tekenreeksen kunnen worden geconverteerd naar bytes met .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 is de standaardconsolecodering sys.getdefaultencoding() == 'ascii'
en niet utf-8
zoals in py3, daarom is afdrukken zoals in het vorige voorbeeld niet direct mogelijk.
>>> 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
Als de codering de tekenreeks niet aankan, wordt een `UnicodeEncodeError` verhoogd:
>>> "£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 naar Unicode
Bytes kunnen worden geconverteerd naar Unicode-tekenreeksen met .decode(encoding)
.
Een reeks bytes kan alleen worden omgezet in een Unicode-reeks via de juiste codering!
>>> b'\xc2\xa313.55'.decode('utf8')
'£13.55'
Als de codering de tekenreeks niet aankan, wordt een UnicodeDecodeError
opgewekt:
>>> 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
Encoding / decoding error handling
.encode
en .decode
beide .decode
.
De standaardwaarde is 'strict'
, wat uitzonderingen op fouten met zich meebrengt. Andere modi zijn meer vergevingsgezind.
codering
>>> "£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'
decoderen
>>> 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'
Moreel
Uit het bovenstaande is duidelijk dat het van vitaal belang is om uw coderingen recht te houden bij het omgaan met unicode en bytes.
Bestand I / O
Bestanden die in een niet-binaire modus worden geopend (bijvoorbeeld 'r'
of 'w'
) behandelen strings. De doveult codering is '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")
Bestanden die zijn geopend in een binaire modus (bijvoorbeeld 'rb'
of 'wb'
) verwerken bytes. Er kan geen coderingsargument worden opgegeven, omdat er geen codering is.
open(fn, mode='wb') # open file for writing bytes
# ERROR: cannot write string when bytes is expected:
open(fn, mode='wb').write("hi")