Вопрос-Ответ

What does the 'b' character do in front of a string literal?

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

По-видимому, следующий синтаксис является допустимым:

b'The string'

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


  1. Что означает этот b символ перед строкой?

  2. Каковы последствия его использования?

  3. В каких ситуациях его следует использовать?

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

Я нашел эту документацию на сайте Python об использовании u символа в том же синтаксисе для указания строки в формате Unicode. К сожалению, символ b нигде в этом документе не упоминается.

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

Переведено автоматически
Ответ 1

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


  • str = '...' литералы = последовательность символов. “Символ” - это базовая единица текста: буква, цифра, знак препинания, символ, пробел или “управляющий символ” (например, табуляция или пробел назад). Стандарт Unicode присваивает каждому символу целую кодовую точку между 0 и 0x10FFFF . (Ну, более или менее. Unicode включает лигатуры и комбинирующие символы, поэтому строка может содержать не такое количество кодовых точек, как воспринимаемые пользователем символы.) Внутренне str использует гибкое строковое представление, которое может использовать 1, 2 или 4 байта на кодовую точку.

  • bytes = b'...' литералы = последовательность байтов. “Байт” - это наименьший целочисленный тип, адресуемый на компьютере, который почти повсеместно является октетом, или 8-битной единицей, что позволяет использовать числа от 0 до 255.

Если вы знакомы с:


  • Java или C #, думайте о str как String и bytes как byte[];

  • SQL, воспринимайте str как NVARCHAR и bytes как BINARY или BLOB;

  • Реестр Windows, думайте о str как REG_SZ и bytes как REG_BINARY.

Если вы знакомы с C (++), то забудьте все, что вы узнали о char и строках, потому что символ - это не байт. Эта идея давно устарела.

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

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

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

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

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

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

И вы можете декодировать a bytes в a 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'...' литералы = последовательность символов Юникода = 3.x str

  • str = '...' литералы = последовательности перепутанных байтов / символов

    • Обычно текст, закодированный в какой-либо неопределенной кодировке.

    • Но также используется для представления двоичных данных, таких как struct.pack выходные данные.



Чтобы упростить переход от 2.x к 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 вместо табуляции), а тройные кавычки '''...''' или """...""" допускают многострочные строковые литералы.

Ответ 2

Цитирую документацию Python 2.x:


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


В документации по Python 3 говорится:


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


Ответ 3

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

Фактическими данными являются байты. Строки - это абстракция.

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

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

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

Ответ 4

Со стороны сервера, если мы отправим какой-либо ответ, он будет отправлен в виде типа byte , поэтому в клиенте он будет отображаться как b'Response from server'

Чтобы избавиться от b'....' просто используйте приведенный ниже код:

Серверный файл:

stri="Response from server"    
c.send(stri.encode())

Клиентский файл:

print(s.recv(1024).decode())

затем он выведет Response from server

python string unicode