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)
(<type 'str'>, '\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)
(<type 'unicode'>, 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)
(<type 'str'>, '\xc3\x84pple')

>>> u16 = v.decode('iso-8859-1').encode('utf-16')
>>> tell_me_about(u16)
(<type 'str'>, '\xff\xfe\xc4\x00p\x00p\x00l\x00e\x00')

>>> tell_me_about(u8.decode('utf8'))
(<type 'unicode'>, u'\xc4pple')

>>> tell_me_about(u16.decode('utf16'))
(<type 'unicode'>, 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 <module>
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 <module>
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ẻ