Вопрос:

байты против байтового массива в Python 2.6 и 3

python python-3.x byte bytearray python-2.x

24659 просмотра

5 ответа

26666 Репутация автора

Я экспериментирую с bytesvs bytearrayв Python 2.6. Я не понимаю причину некоторых различий.

bytesИтератора возвращает строку:

for i in bytes(b"hi"):
    print(type(i))

дает:

<type 'str'>
<type 'str'>

Но bytearrayитератор возвращает ints:

for i in bytearray(b"hi"):
    print(type(i))

дает:

<type 'int'>
<type 'int'>

Почему разница?

Я хотел бы написать код, который будет хорошо переведен на Python 3. Итак, такая же ситуация в Python 3?

Автор: Craig McQueen Источник Размещён: 16.11.2009 07:50

Ответы (5)


3 плюса

45704 Репутация автора

Я не уверен, с какой версии, но bytesна самом деле это str, который вы можете увидеть, если вы делаете type(bytes(b"hi"))-> <type 'str'>.

bytearray изменяемый массив байтов, один конструктор которого принимает строку.

Автор: van Размещён: 16.11.2009 08:09

25 плюса

58866 Репутация автора

Решение

В Python 2.6 байты являются просто псевдонимом для str .
Этот «псевдотип» был введен для [частичной] подготовки программ [и программистов!] К конвертации / совместимости с Python 3.0, где существует строгое различие в семантике и использовании для str (которые систематически являются Unicode) и байтов (которые являются массивами). октетов, для хранения данных, но не текста)

Точно так же префикс b для строковых литералов неэффективен в 2.6, но это полезный маркер в программе, который явно обозначает намерение программиста иметь строку в качестве строки данных, а не текстовой строки. Эта информация может затем использоваться конвертером 2to3 или подобными утилитами, когда программа портирована на Py3k.

Вы можете проверить этот вопрос SO для получения дополнительной информации.

Автор: mjv Размещён: 16.11.2009 08:09

3 плюса

26666 Репутация автора

Я попробовал это на Python 3.0.

В Python 3.0 bytesитератор возвращает ints, а не строки, как в Python 2.6:

for i in bytes(b"hi"):
    print(type(i))

дает:

<class 'int'>
<class 'int'>

bytearrayИтератор возвращает class 'int'с.

Автор: Craig McQueen Размещён: 19.11.2009 02:37

3 плюса

391 Репутация автора

Для (как минимум) Python 3.7

Согласно документам:

bytes объекты являются неизменяемыми последовательностями из одного байта

bytearray объекты являются изменяемым аналогом байтовых объектов.

И это в значительной степени это так, как bytesпротив bytearray. На самом деле они достаточно взаимозаменяемы и разработаны достаточно гибкими, чтобы их можно было смешивать в операциях без ошибок. Фактически, в официальной документации есть целый раздел, посвященный тому, чтобы показать сходство между bytesи bytearrayapis.

Некоторые подсказки относительно того, почему из документов:

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

Автор: Harsha Goli Размещён: 13.12.2018 03:43

0 плюса

87 Репутация автора

bytesи strизменили значение в python начиная с python 3.x.

Сначала ответим на ваш вопрос в Python 2.6bytes(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литерал будет означать a byteв python2.6 +. Ну, этот ответ объясняет, что

В Python 3.x an 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тип в Python 3 и unicodeтип в Python 2).

Проще говоря

python2.6 + bytes= python2.6 + str= python3.x bytes! = python3.xstr

python2.6 + bytearray= python3.xbytearray

python2.x unicode= python3.xstr

Автор: Rajeshwar Agrawal Размещён: 31.01.2019 02:46
Вопросы из категории :
32x32