Ответы:
Предполагая 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'
str
недоступно или не актуально со стороны Python; структура данных - это просто последовательность кодовых точек. В соответствии с PEP 393 точное внутреннее кодирование является латинским-1, UCS2 или UCS4, и представление utf-8 может быть кэшировано после первого запроса, но даже коду C не рекомендуется полагаться на эти внутренние детали.
Единственное, что может хранить компьютер - это байты.
Чтобы сохранить что-либо на компьютере, вы должны сначала закодировать его, то есть преобразовать в байты. Например:
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 строка байтов представлена символом a b
, за которым следует представление строки байтов ASCII
.
Строка байтов может быть декодирована обратно в строку символов, если вы знаете кодировку, которая использовалась для ее кодирования.
b'I am a string'.decode('ASCII')
Приведенный выше код вернет исходную строку 'I am a string'
.
Кодирование и декодирование являются обратными операциями. Все должно быть закодировано, прежде чем оно может быть записано на диск, и оно должно быть декодировано, прежде чем оно может быть прочитано человеком.
Примечание: я более подробно остановлюсь на моем ответе для Python 3, так как конец жизни Python 2 очень близок.
В питоне 3
bytes
состоит из последовательностей 8-битных значений без знака, а str
состоит из последовательностей кодовых точек Unicode, которые представляют текстовые символы из человеческих языков.
>>> # bytes
>>> b = b'h\x65llo'
>>> type(b)
<class 'bytes'>
>>> list(b)
[104, 101, 108, 108, 111]
>>> print(b)
b'hello'
>>>
>>> # str
>>> s = 'nai\u0308ve'
>>> type(s)
<class 'str'>
>>> list(s)
['n', 'a', 'i', '̈', 'v', 'e']
>>> print(s)
naïve
Несмотря на то, bytes
и str
кажется, работают точно так же, их экземпляры не совместимы друг с другом, то есть bytes
и str
экземпляры не могут быть использованы вместе с операторами , как >
и +
. Кроме того, имейте в виду, что сравнение bytes
и str
примеры на равенство, то есть использование ==
, всегда будут оцениваться, False
даже если они содержат абсолютно одинаковые символы.
>>> # concatenation
>>> b'hi' + b'bye' # this is possible
b'hibye'
>>> 'hi' + 'bye' # this is also possible
'hibye'
>>> b'hi' + 'bye' # this will fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>> 'hi' + b'bye' # this will also fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>>
>>> # comparison
>>> b'red' > b'blue' # this is possible
True
>>> 'red'> 'blue' # this is also possible
True
>>> b'red' > 'blue' # you can't compare bytes with str
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'bytes' and 'str'
>>> 'red' > b'blue' # you can't compare str with bytes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'bytes'
>>> b'blue' == 'red' # equality between str and bytes always evaluates to False
False
>>> b'blue' == 'blue' # equality between str and bytes always evaluates to False
False
Еще одна проблема при работе с bytes
и str
присутствует при работе с файлами, которые возвращаются с помощью open
встроенной функции. С одной стороны, если вы хотите не читать или записывать двоичные данные в / из файла, всегда открывайте файл в двоичном режиме, таком как «rb» или «wb». С другой стороны, если вы хотите читать или записывать данные Unicode в / из файла, помните о кодировке вашего компьютера по умолчанию, поэтому при необходимости передайте encoding
параметр, чтобы избежать неожиданностей.
В Python 2
str
состоит из последовательностей 8-битных значений, а unicode
состоит из последовательностей символов Unicode. Одна вещь , чтобы иметь в виду, что str
и unicode
может быть использовано вместе с операторами , если str
состоит только из 7-битовых символов ASCI.
Может быть полезно использовать вспомогательные функции для преобразования между str
и unicode
в Python 2, а также между bytes
и str
в Python 3.
Из Что такое 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 (другая серия битов) или любого другого представления (серии битов). ).
Для обмена информацией стороны в сообщении должны договориться о том, какое представительство будет использовано.
Поскольку юникод стремится представлять все возможные символы (и другие «вещи»), используемые в меж-человеческом и межкомпьютерном общении, ему требуется большее количество бит для представления многих символов (или вещей), чем в других системах представления, которые стремиться представлять более ограниченный набор символов / вещей. Чтобы «упростить» и, возможно, учесть историческое использование, представление в юникоде почти исключительно преобразуется в какую-то другую систему представления (например, ascii) с целью хранения символов в файлах.
Это не тот случай, юникод не может быть использован для хранения символов в файлах, или передавать их через любой канал связи, просто , что это не так .
Термин «строка» точно не определен. «Строка» в своем обычном использовании относится к набору символов / вещей. В компьютере эти символы могут храниться в любом из множества различных побитовых представлений. «Строка байтов» - это набор символов, хранящихся с использованием представления, которое использует восемь битов (восемь битов упоминаются как байт). Поскольку в наши дни компьютеры используют систему Unicode (символы, представленные переменным числом байтов) для хранения символов в памяти, а строки байтов (символы, представленные одиночными байтами) для хранения символов в файлах, преобразование должно быть использовано перед символами, представленными в памяти будут перемещены в хранилище в файлах.
Давайте получим простую односимвольную строку 'š'
и закодируем ее в последовательность байтов:
>>> 'š'.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))
'š'
Языки Python включают в себя str
и в bytes
качестве стандарта "Встроенные типы". Другими словами, они оба классы. Я не думаю, что стоит пытаться объяснить, почему Python был реализован таким образом.
Сказав это, str
и bytes
очень похожи друг на друга. Оба используют одни и те же методы. Следующие методы являются уникальными для str
класса:
casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable
Следующие методы являются уникальными для bytes
класса:
decode
fromhex
hex
str
тип совпадает сbytes
типом; этот ответ эквивалентно сравниваетunicode
тип (не существует в Python 3) сstr
типом.