TL; DR
python2.6 + bytes
= python2.6 + str
= python3.x bytes
! = Python3.x str
python2.6 + bytearray
= python3.x bytearray
python2.x unicode
= python3.x str
Длинный ответ
bytes
и str
изменили значение в python начиная с python 3.x.
Сначала коротко ответим на ваш вопрос , в python 2.6 bytes(b"hi")
- это неизменяемый массив байтов (8-бит или октет). Таким образом, тип каждого byte
просто byte
, что совпадает с str
в Python 2.6+ (однако в Python 3.x это не так)
bytearray(b"hi")
снова изменяемый массив байтов. Но когда вы спрашиваете его тип, это int
, потому что python представляет каждый элемент bytearray
как целое число в диапазоне 0-255 (все возможные значения для 8-битного целого). Однако элемент массива bytes
представляется как значение ASCII этого байта.
Например, рассмотрим в Python 2.6 +
>>> barr=bytearray(b'hi')
>>> bs=bytes(b'hi')
>>> barr[0] # python shows you an int value for the 8 bits 0110 1000
104
>>> bs[0] # python shows you an ASCII value for the 8 bits 0110 1000
'h'
>>> chr(barr[0]) # chr converts 104 to its corresponding ASCII value
'h'
>>> bs[0]==chr(barr[0]) # python compares ASCII value of 1st byte of bs and ASCII value of integer represented by first byte of barr
True
Теперь Python 3.x - это совсем другая история. Как вы могли догадаться, странно, почему литерал str
будет означать byte
в python2.6 +. Ну этот ответ объясняет, что
В Python 3.x str
- это текст в Unicode (который ранее был просто массивом байтов, обратите внимание, что Unicode и байты - это две совершенно разные вещи). bytearray
- это массив изменяемых байтов, а bytes
- это массив неизменных байтов. Они оба имеют почти одинаковые функции. Теперь, если я снова запускаю тот же код в Python 3.x, вот результат. В Python 3.x
>>> barr=bytearray(b'hi')
>>> bs=bytes(b'hi')
>>> barr[0]
104
>>> bs[0]
104
>>> bs[0]==barr[0] # bytes and bytearray are same thing in python 3.x
True
bytes
и bytearray
- это то же самое в Python 3.x, за исключением изменчивости.
Что случилось с str
, спросите вы? str
в Python 3 был преобразован в то, что unicode
было в Python 2, и тип unicode
был впоследствии удален из Python 3, так как он был избыточным.
Я хотел бы написать код, который будет хорошо транслироваться на Python 3. Итак, такая же ситуация в Python 3?
Это зависит от того, что вы пытаетесь сделать. Вы имеете дело с байтами или с ASCII представлением байтов?
Если вы имеете дело с байтами , то я советую использовать bytearray
в Python 2, то же самое в Python 3. Но вы теряете неизменность, если это важно для вас.
Если вы имеете дело с ASCII или текстом , то представьте свою строку как u'hi'
в Python 2, что имеет то же значение в Python 3. 'u'
имеет особое значение в Python 2, который инструктирует python 2 обрабатывать строковый литерал как тип unicode
. 'u' в Python 3 не имеет смысла, потому что все строковые литералы в Python 3 по умолчанию являются Unicode (который в смежных целях называется str
type в python 3 и unicode
type в python 2)