Что делает символ «b» перед строковым литералом?

По-видимому, следующий синтаксис …

my_string = b'The string' 

Я бы хотел знать…

  1. Что означает этот символ b символа строки?
  2. Каковы последствия его использования?
  3. Каковы подходящие ситуации для его использования.

Я нашел связанный вопрос прямо здесь, на SO, но этот вопрос касается PHP, хотя и указывает, что b используется для указания, что строка является двоичной, а не unicode, которая необходима для того, чтобы код был совместим с версией PHP <6 при переносе на PHP 6. Я не думаю, что это относится к Python.

Я нашел эту документацию на сайте python об использовании символа u в том же синтаксисе, чтобы указать строку как unicode. К сожалению, он не упоминает символ b нигде в этом документе.

Кроме того, только из любопытства, есть ли больше символов, чем b и u которые делают другие вещи?

Чтобы процитировать документацию Python 2.x :

Префикс «b» или «B» игнорируется в Python 2; он указывает, что литерал должен быть литералом байтов в Python 3 (например, когда код автоматически преобразуется с 2to3). Префикс 'u' или 'b' может сопровождаться префиксом 'r'.

В документации Python 3.3 указано:

Литералы байтов всегда имеют префикс «b» или «B»; они генерируют экземпляр типа байтов вместо типа str. Они могут содержать только символы ASCII; байты с числовым значением 128 или выше должны быть выражены с помощью экранов.

Python 3.x делает четкое различие между типами:

  • str = '...' literals = последовательность символов Unicode (UTF-16 или UTF-32, в зависимости от того, как был скомпилирован Python)
  • bytes = b'...' literals = последовательность октетов (целые числа от 0 до 255)

Если вы знакомы с Java или C #, подумайте о str как String и bytes as byte[] . Если вы знакомы с SQL, NVARCHAR str как NVARCHAR а bytesBINARY или BLOB . Если вы знакомы с реестром Windows, подумайте о str как REG_SZ и bytes как REG_BINARY . Если вы знакомы с C (++), забудьте все, что вы узнали о char и строках, потому что ХАРАКТЕР НЕ БЫТЬ . Эта идея давно устарела.

Вы используете str когда хотите представить текст.

 print('שלום עולם') 

Вы используете bytes когда хотите представлять низкоуровневые двоичные данные, такие как structs.

 NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0] 

Вы можете кодировать str в объект bytes .

 >>> '\uFEFF'.encode('UTF-8') b'\xef\xbb\xbf' 

И вы можете декодировать bytes в str .

 >>> b'\xE2\x82\xAC'.decode('UTF-8') '€' 

Но вы не можете свободно смешивать два типа.

 >>> b'\xEF\xBB\xBF' + 'Text with a UTF-8 BOM' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't concat bytes to str 

Обозначение b'...' несколько сбивает с толку, поскольку оно позволяет указать байты 0x01-0x7F с символами ASCII вместо шестнадцатеричных чисел.

 >>> b'A' == b'\x41' True 

Но я должен подчеркнуть, что персонаж не байт .

 >>> 'A' == b'A' False 

В Python 2.x

В версиях версии Python версии 3.0 не было такого различия между текстовыми и двоичными данными. Вместо этого было:

  • unicode = u'...' literals = последовательность символов Unicode = 3.x str
  • str = '...' litals = последовательности смешанных байтов / символов
    • Обычно текст, закодированный в некоторой неопределенной кодировке.
    • Но также используется для представления двоичных данных, таких как struct.pack output.

Чтобы облегчить переход 2.x-to-3.x, синтаксис b'...' был передан в Python 2.6, чтобы позволить различать двоичные строки (которые должны быть bytes в 3.x) из текста строки (которые должны быть str в 3.x). Префикс b ничего не делает в 2.x, но говорит сценарию 2to3 не преобразовывать его в строку Unicode в 3.x.

Так что да, b'...' литералы в Python имеют ту же цель, что и в PHP.

Кроме того, только из любопытства, есть ли больше символов, чем b и u, которые делают другие вещи?

Префикс r создает необработанную строку (например, r'\t' – обратная косая черта + t вместо вкладки), а тройные кавычки '''...''' или """...""" позволяют multi Строковые литералы.

B обозначает байтовую строку.

Байт – это фактические данные. Строки – это абстракция.

Если у вас был многосимвольный строковый объект, и вы взяли один символ, это будет строка, и размер может быть более 1 байта в зависимости от кодировки.

Если взять 1 байт с байтовой строкой, вы получите одно 8-битное значение от 0-255, и оно может не представлять полный символ, если эти символы из-за кодирования были> 1 байт.

TBH Я бы использовал строки, если у меня не было определенной причины низкого уровня использования байтов.

Он превращает его в bytes литерал (или str в 2.x) и действителен для 2.6+.

Префикс r вызывает обратную косую черту как «неинтерпретированную» (не игнорируется, и разница имеет значение).

Вот пример, в котором отсутствие «b» генерирует исключение TypeError в Python 3.x

 >>> f=open("new", "wb") >>> f.write("Hello Python!") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' does not support the buffer interface 

Добавление префикса 'b' устранит проблему.