Это наблюдение
... что меня действительно удивляет, что я могу декодировать b1 и b2, и они оба восстанавливаются до исходной строки:
b1.decode('utf-16') == b2.decode('utf-16')
True
предлагаетесть встроенное значение по умолчанию, потому что для 16-битных кодов UTF-16 есть два возможных варианта: Big and Little Endian .
Обычно Python выводит порядковый номер для использованияиз спецификации при чтении - и поэтому всегда добавляет один при записи.Если вы хотите задать конкретный порядок байтов, вы можете использовать явные кодировки utf-16-le
и utf-16-be
:
… при использовании такой кодировки спецификация будет автоматически записана как первый символи будет молча отброшен при чтении файла.Существуют варианты этих кодировок, такие как «utf-16-le» и «utf-16-be» для кодировок с прямым порядком байтов и с прямым порядком байтов, которые задают один конкретный порядок байтов и не пропускают спецификацию.
(https://docs.python.org/3/howto/unicode.html#reading-and-writing-unicode-data)
Но если вы не используете конкретный порядок, то какой используется по умолчанию? Исходное предложение Unicode, PEP 100, предупреждает
Примечание:'utf-16' должен быть реализован с использованием и требовать меток порядка байтов (BOM) для ввода / вывода файла.
(https://www.python.org/dev/peps/pep-0100/, my emph.)
Все же это работает для вас. Если мы посмотрим в исходном коде Python, как это делается, мы найдем этот комментарий в _codecsmodule.c
:
/* This version provides access to the byteorder parameter of the
builtin UTF-16 codecs as optional third argument. It defaults to 0
which means: use the native byte order and prepend the data with a
BOM mark.
*/
и глубже, в unicodeobject.c
,
/* Check for BOM marks (U+FEFF) in the input and adjust current
byte order setting accordingly. In native mode, the leading BOM
mark is skipped, in all other modes, it is copied to the output
stream as-is (giving a ZWNBSP character). */
Итак, изначально порядок байтов установлен по умолчанию для вашей системы, и когда вы начинаете декодировать данные UTF-16, а затем следует спецификация, порядок байтов устанавливается равным всему, что это указывает.порядок "в этом последнем комментарии относится к тому, был ли определенный порядок байтов явно объявлен ИЛИ имеет bвстречаются с помощью спецификации;и когда ни один из них не соответствует истине, он будет использовать порядковый номер вашей системы.