В чем разница между строкой и байтовой строкой?

Я работаю с библиотекой, которая возвращает байтовую строку, и мне нужно преобразовать ее в строку.

Хотя я не уверен, в чем разница - если таковые имеются.

9 ответов

Решение

Предполагая Python 3 (в Python 2 эта разница немного менее четко определена) - строка представляет собой последовательность символов, то есть кодовые точки Юникода; это абстрактная концепция, и ее нельзя сохранить непосредственно на диске. Строка байтов - это, что неудивительно, последовательность байтов - вещей, которые можно хранить на диске. Отображение между ними представляет собой кодировку - их довольно много (и бесконечно много возможно) - и вам нужно знать, что применяется в конкретном случае, чтобы выполнить преобразование, поскольку другая кодировка может отображать одни и те же байты в другую строку:

>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16')
'蓏콯캁澽苏'
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8')
'τoρνoς'

Как только вы знаете, какой из них использовать, вы можете использовать .decode() метод байтовой строки, чтобы получить правильную символьную строку из нее, как указано выше. Для полноты .encode() метод символьной строки идет в обратном направлении:

>>> 'τoρνoς'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'

Единственное, что может хранить компьютер - это байты.

Чтобы сохранить что-либо на компьютере, вы должны сначала закодировать его, то есть преобразовать в байты. Например:

  • Если вы хотите хранить музыку, вы должны сначала закодировать ее, используя MP3, WAV, так далее.
  • Если вы хотите сохранить изображение, вы должны сначала закодировать его, используя PNG, JPEG, так далее.
  • Если вы хотите сохранить текст, вы должны сначала закодировать его, используя ASCII, UTF-8, так далее.

MP3, WAV, PNG, JPEG, ASCII а также UTF-8 примеры кодировок. Кодировка - это формат для представления аудио, изображений, текста и т. Д. В байтах.

В Python байтовая строка - это всего лишь последовательность байтов. Это не для человека. Под капотом все должно быть преобразовано в строку байтов, прежде чем она может быть сохранена в компьютере.

С другой стороны, строка символов, часто называемая просто "строка", представляет собой последовательность символов. Это читабельно для человека. Строка символов не может быть напрямую сохранена на компьютере, она должна быть сначала закодирована (преобразована в строку байтов). Существует несколько кодировок, посредством которых символьная строка может быть преобразована в байтовую строку, например ASCII а также UTF-8,

'I am a string'.encode('ASCII')

Приведенный выше код Python закодирует строку 'I am a string' используя кодировку ASCII, Результатом вышеприведенного кода будет байтовая строка. Если вы распечатаете его, Python представит его как b'I am a string', Помните, однако, что строки байтов не читаются человеком, просто Python декодирует их из ASCII когда вы печатаете их. В Python байтовая строка представлена bсопровождаемый байтовой строкой ASCII представление.

Строка байтов может быть декодирована обратно в строку символов, если вы знаете кодировку, которая использовалась для ее кодирования.

b'I am a string'.decode('ASCII')

Приведенный выше код вернет исходную строку 'I am a string',

Кодирование и декодирование являются обратными операциями. Все должно быть закодировано, прежде чем оно может быть записано на диск, и оно должно быть декодировано, прежде чем оно может быть прочитано человеком.

В Python 2str состоит из последовательностей 8-битных значений, в то время как unicode состоит из последовательностей символов Unicode. Следует иметь в виду, что str а также unicode может использоваться вместе с операторами, если str состоит только из 7-битных символов ASCI.

В Python 3bytes состоит из последовательностей 8-битных значений, в то время как str состоит из последовательностей символов Unicode. bytes а также strне может использоваться вместе с такими операторами, как > или же +,

Может быть полезно использовать вспомогательные функции для преобразования между str а также unicode в Python 2 и между bytes а также str в Python 3.

У нас будет простая односимвольная строка 'š' и закодируем его в последовательность байтов:

>>> 'š'.encode('utf-8')
b'\xc5\xa1'

Для этого примера давайте отобразим последовательность байтов в двоичной форме:

>>> bin(int(b'\xc5\xa1'.hex(), 16))
'0b1100010110100001'

Теперь, как правило, невозможно декодировать информацию, не зная, как она была закодирована. Только если вы знаете, чтоutf-8использовалась кодировка текста, вы можете следовать алгоритму декодирования utf-8 и получить исходную строку:

11000101 10100001
   ^^^^^   ^^^^^^
   00101   100001

Вы можете отображать двоичное число 101100001 обратно в виде строки:

>>> chr(int('101100001', 2))
'š'

Из того, что такое Unicode:

По сути, компьютеры работают только с числами. Они хранят буквы и другие символы, назначая номера для каждого.

......

Unicode предоставляет уникальный номер для каждого символа, независимо от того, какая платформа, какая программа, какой язык.

Поэтому, когда компьютер представляет строку, он находит символы, хранящиеся в компьютере строки, через их уникальный номер Unicode, и эти цифры сохраняются в памяти. Но вы не можете напрямую записать строку на диск или передать строку по сети через их уникальный номер Unicode, потому что эти цифры - просто простое десятичное число. Вы должны закодировать строку в байтовую строку, такую ​​как UTF-8, UTF-8 является кодировкой символов, способной кодировать все возможные символы, и она хранит символы в байтах (это выглядит так). Таким образом, закодированная строка может использоваться везде, потому что UTF-8 почти везде поддерживается. Когда вы открываете текстовый файл, закодированный в UTF-8 из других систем ваш компьютер будет декодировать его и отображать символы в нем через уникальный номер Unicode. Когда браузер получает строковые данные в кодировке UTF-8 из сети, он будет декодировать данные в строку (предположим, что браузер в UTF-8 кодирование) и отобразить строку.

В python3 вы можете преобразовывать строки и байты друг в друга:

>>> print('中文'.encode('utf-8'))
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
中文 

Одним словом, строка предназначена для показа людям для чтения на компьютере, а строка байтов - для сохранения на диск и передачи данных.

Юникод - это согласованный формат для двоичного представления символов и различных видов форматирования (например, нижний / верхний регистр, новая строка, возврат каретки) и других "вещей" (например, эмодзи). Компьютер не менее способен хранить представление Unicode (последовательность битов), будь то в памяти или в файле, чем хранить представление ascii (другая последовательность битов) или любое другое представление (последовательность битов).

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

Поскольку Unicode стремится представить все возможные символы (и другие "вещи"), используемые в межчеловеческом и межкомпьютерном общении, он требует большего количества битов для представления многих символов (или вещей), чем другие системы представления, которые стремятся представить более ограниченный набор персонажей / вещей. Чтобы "упростить" и, возможно, приспособиться к историческому использованию, представление Unicode почти исключительно преобразуется в какую-либо другую систему представления (например, ascii) с целью хранения символов в файлах.

Это не тот случай, юникод не может быть использован для хранения символов в файлах, или передавать их через любой канал связи, просто, что это не так.

Термин "строка" точно не определен. "Строка" в ее обычном употреблении относится к набору символов / вещей. В компьютере эти символы могут храниться в любом из множества различных побитовых представлений. "Строка байтов" - это набор символов, хранящийся с использованием представления, использующего восемь битов (восемь битов называются байтами). Поскольку в наши дни компьютеры используют систему юникода (символы, представленные переменным числом байтов) для хранения символов в памяти и байтовые строки (символы, представленные отдельными байтами) для хранения символов в файлы, преобразование должно использоваться до представления символов. в памяти будет перемещен в хранилище в файлах.

Строка - это связка элементов, соединенных вместе. Строка байтов - это последовательность байтов, например b'\xce\xb1\xce\xac'который представляет. Символьная строка - это набор символов, например "αά". Синоним последовательности. Байтовая строка может быть напрямую сохранена на диске, в то время как строка (символьная строка) не может быть напрямую сохранена на диске. Отображение между ними - это кодировка.

Проще говоря, представьте себе наши естественные языки, такие как английский, бенгали, китайский и т. Д. Во время разговора все эти языки издают звук. Но понимаем ли мы их всех, даже если мы их здесь? - Ответ вообще отрицательный. Итак, если я говорю, что понимаю английский, это означает, что я знаю, как эти звуки кодируются в некоторые значимые английские слова, и я просто декодирую эти звуки таким же образом, чтобы понимать их. То же самое и с любым другим языком: если вы его знаете, у вас в голове уже есть пакет кодировщика-декодера для этого языка, опять же, если вы его не знаете, у вас его просто нет.

То же самое и с цифровыми системами. Как и мы сами, поскольку мы можем слышать звуки только ушами и издавать звук ртом, компьютеры могут только хранить байты и читать байты. Таким образом, определенное приложение знает, как читать байты и интерпретировать их (например, сколько байтов следует учитывать, чтобы понять любую информацию), а также записывать таким же образом, чтобы другие приложения также понимали это. Но без понимания (кодировщика-декодера) все данные, записываемые на диск, представляют собой просто строки байтов.

Языки Python включают str а также bytesкак стандартные "встроенные типы". Другими словами, они оба класса. Я не думаю, что стоит пытаться объяснить, почему Python был реализован таким образом.

Было сказано, что, str а также bytesочень похожи друг на друга. Оба используют почти одинаковые методы. Следующие методы уникальны дляstr учебный класс:

casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable

Следующие методы уникальны для bytes учебный класс:

decode
fromhex
hex
Другие вопросы по тегам