Hướng dẫn encoding iso-8859-1 python

Đâ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ó utiề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 strlà 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 unicodelà 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 printlệnh có logic riêng của nó để mã hóa , thiết lập để sys.stdout.encodingvà mặc định là UTF-8
  • Người ta phải giải mã a strthà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ẻ

Chủ Đề