Ответы:
Предполагая 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типом.