Đây là một vấn đề phổ biến, vì vậy đây là một minh họa tương đối kỹ lưỡng.
Đối với các chuỗi không phải là unicode [tức là các chuỗi không có u
tiền tố như u'\xc4pple'
], người ta phải giải mã từ mã hóa gốc [ iso8859-1
/ latin1
, trừ khi
được sửa đổi bằngsys.setdefaultencoding
hàm enigmatic ] unicode
, sau đó mã hóa thành một bộ ký tự có thể hiển thị các
ký tự bạn muốn, trong trường hợp này tôi 'khuyên bạn nên UTF-8
.
Đầu tiên, đây là một hàm tiện ích tiện dụng sẽ giúp chiếu sáng các mẫu của chuỗi Python 2.7 và unicode:
>>> def tell_me_about[s]: return [type[s], s]
Một chuỗi đơn giản
>>> v = "\xC4pple" # iso-8859-1 aka latin1 encoded string
>>> tell_me_about[v]
[, '\xc4pple']
>>> v
'\xc4pple' # representation in memory
>>> print v
?pple # map the iso-8859-1 in-memory to iso-8859-1 chars
# note that '\xc4' has no representation in iso-8859-1,
# so is printed as "?".
Giải mã chuỗi iso8859-1 - chuyển đổi chuỗi đơn giản thành unicode
>>> uv = v.decode["iso-8859-1"]
>>> uv
u'\xc4pple' # decoding iso-8859-1 becomes unicode, in memory
>>> tell_me_about[uv]
[, u'\xc4pple']
>>> print v.decode["iso-8859-1"]
Äpple # convert unicode to the default character set
# [utf-8, based on sys.stdout.encoding]
>>> v.decode['iso-8859-1'] == u'\xc4pple'
True # one could have just used a unicode representation
# from the start
Minh họa thêm một chút - với
>>> u"Ä" == u"\xc4"
True # the native unicode char and escaped versions are the same
>>> "Ä" == u"\xc4"
False # the native unicode char is '\xc3\x84' in latin1
>>> "Ä".decode['utf8'] == u"\xc4"
True # one can decode the string to get unicode
>>> "Ä" == "\xc4"
False # the native character and the escaped string are
# of course not equal ['\xc3\x84' != '\xc4'].
Mã hóa thành UTF
>>> u8 = v.decode["iso-8859-1"].encode["utf-8"]
>>> u8
'\xc3\x84pple' # convert iso-8859-1 to unicode to utf-8
>>> tell_me_about[u8]
[, '\xc3\x84pple']
>>> u16 = v.decode['iso-8859-1'].encode['utf-16']
>>> tell_me_about[u16]
[, '\xff\xfe\xc4\x00p\x00p\x00l\x00e\x00']
>>> tell_me_about[u8.decode['utf8']]
[, u'\xc4pple']
>>> tell_me_about[u16.decode['utf16']]
[, u'\xc4pple']
Mối quan hệ giữa unicode và UTF và latin1
>>> print u8
Äpple # printing utf-8 - because of the encoding we now know
# how to print the characters
>>> print u8.decode['utf-8'] # printing unicode
Äpple
>>> print u16 # printing 'bytes' of u16
���pple
>>> print u16.decode['utf16']
Äpple # printing unicode
>>> v == u8
False # v is a iso8859-1 string; u8 is a utf-8 string
>>> v.decode['iso8859-1'] == u8
False # v.decode[...] returns unicode
>>> u8.decode['utf-8'] == v.decode['latin1'] == u16.decode['utf-16']
True # all decode to the same unicode memory representation
# [latin1 is iso-8859-1]
Ngoại lệ Unicode
>>> u8.encode['iso8859-1']
Traceback [most recent call last]:
File "", line 1, in
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range[128]
>>> u16.encode['iso8859-1']
Traceback [most recent call last]:
File "", line 1, in
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0:
ordinal not in range[128]
>>> v.encode['iso8859-1']
Traceback [most recent call last]:
File "", line 1, in
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0:
ordinal not in range[128]
Người ta sẽ khắc phục điều này bằng cách chuyển đổi từ mã hóa cụ thể [latin-1, utf8, utf16] sang unicode, vd u8.decode['utf8'].encode['latin1']
.
Vì vậy, có lẽ người ta có thể rút ra các nguyên tắc và khái quát sau đây:
- một loại
str
là một tập hợp các byte, có thể có một trong số các mã hóa như Latin-1, UTF-8 và UTF-16 - một loại
unicode
là một tập hợp các byte có thể được chuyển đổi thành bất kỳ số lượng mã hóa nào, phổ biến nhất là UTF-8 và latin-1 [iso8859-1] - các
print
lệnh có logic riêng của nó để mã hóa , thiết lập đểsys.stdout.encoding
và mặc định là UTF-8 - Người ta phải giải mã a
str
thành unicode trước khi chuyển đổi sang mã hóa khác.
Tất nhiên, tất cả những thay đổi này trong Python 3.x.
Hy vọng rằng được chiếu sáng.
đọc thêm
- Nhân vật so với Byte , bởi Tim Bray.
Và những lời tán dương rất minh họa của Armin Ronacher:
- Hướng dẫn cập nhật về Unicode trên Python [ngày 2 tháng 7 năm 2013]
- Thêm về Unicode trong Python 2 và 3 [ngày 5 tháng 1 năm 2014]
- UCS vs UTF-8 dưới dạng mã hóa chuỗi nội bộ [ngày 9 tháng 1 năm 2014]
- Mọi thứ bạn không muốn biết về Unicode trong Python 3 [ngày 12 tháng 5 năm 2014]
136 hữu ích 2 bình luận chia sẻ