Какую кодировку использует python при создании байтов с префиксом «b» перед строкой? - PullRequest
0 голосов
/ 02 августа 2020

Из python до c:

Байтовые литералы всегда имеют префикс 'b' или 'B'; они создают экземпляр типа bytes вместо типа str. Они могут содержать только символы ASCII; байты со значением numeri c 128 или больше должны быть выражены с помощью escape-символов.

Я знаю, что могу создать объект bytes с префиксным выражением b, например: b'cool', это будет преобразовать строку Юникода 'cool' в байты. Я также знаю, что экземпляр байтов может быть создан функцией bytes(), но вам нужно указать аргумент кодировки: bytes('cool', 'utf-8').

Насколько я понимаю, мне нужно использовать одно из правил кодирования, если я хотите преобразовать строку в последовательность байтов. Я провел несколько экспериментов, и мне кажется, что префикс b преобразует строку в байты с использованием кодировки utf-8:

>>> a = bytes('a', 'utf-8')
>>> b'a' == a
True
>>> b = bytes('a', 'utf-16')
>>> b'a' == b
False

Мой вопрос: при создании объекта байтов через префикс b, какая кодировка делает python использовать? Есть ли какой-нибудь do c, задающий этот вопрос? Использует ли он по умолчанию utf-8 или ascii?

1 Ответ

1 голос
/ 02 августа 2020

Тип bytes может содержать произвольные данные. Например, (начало) изображения JPEG:

>>> with open('Bilder/19/01/IMG_3388.JPG', 'rb') as f:
...     head = f.read(10)

Вы должны думать об этом как о последовательности целых чисел. Это также то, как тип ведет себя во многих аспектах:

>>> list(head)
[255, 216, 255, 225, 111, 254, 69, 120, 105, 102]
>>> head[0]
255
>>> sum(head)
1712

Из соображений удобства (и, я полагаю, по историческим причинам) стандартное repr представление байтов и их литералов аналогично строки:

>>> head
b'\xff\xd8\xff\xe1o\xfeExif'

Там, где это возможно, используются печатаемые символы ASCII, иначе \xNN экранирует. Это удобно, если объект bytes представляет текст:

>>> 'Zoë'.encode('utf8')
b'Zo\xc3\xab'
>>> 'Zoë'.encode('utf16')
b'\xff\xfeZ\x00o\x00\xeb\x00'
>>> 'Zoë'.encode('latin1')
b'Zo\xeb'

Когда вы вводите bytes литералы, Python использует ASCII для их декодирования. Символы в диапазоне ASCII кодируются таким же образом в UTF-8, поэтому вы наблюдали эквивалентность b'a' == bytes('a', 'utf8'). Немного менее вводящим в заблуждение могло бы быть выражение b'a' == bytes('a', 'ascii').

...