2015-01-31 5 views
13

Я пытаюсь получить первый символ байт-строку в Python 3.4, но когда я индексировать его, я получаю int:Почему я получаю int при индексировании байтов?

>>> my_bytes = b'just a byte string' 
b'just a byte string' 
>>> my_bytes[0] 
106 
>>> type(my_bytes[0]) 
<class 'int'> 

Это кажется неинтуитивным мне, как я ожидал получить b'j'.

Я обнаружил, что могу получить ценность, которую я ожидаю, но для меня это похоже на хак.

>>> my_bytes[0:1] 
b'j' 

Может кто-нибудь объяснить, почему это происходит?

+1

Не уверен, почему я заслужил нисходящий и заочный за это. Может кто-нибудь объяснить, как можно улучшить этот вопрос? – meshy

+3

Я не голосовал; Я думаю, кто-то чувствовал, что это очевидно для них, и в документации говорится, что это происходит для типа. Закрытие голосования вне базы (* Непонятно *? Это совершенно ясный вопрос для меня). –

+1

Хак с использованием диапазона, например 'my_bytes [0: 1]' действительно помог мне написать Python2/Python3 совместимый код. Мне бы хотелось увидеть ответ, который охватывает наилучшую практику для совместимого кода для решения этой проблемы. Например: 'ord (my_bytes [0])' дает int в Python2, но 'my_bytes [0]' дает int в Python3. Чтобы работать в обоих, я использую 'ord (my_bytes [0: 1])', который кажется действительно уродливым для Python3. – proximous

ответ

13

Тип bytes является Binary Sequence type, и явно задокументирован как содержащая последовательность целых чисел в диапазоне от 0 до 255.

Из документации:

Bytes объектов являются неизменяемой последовательностью одиночных байт ,

[...]

Хотя байтов литералов и представления основаны на ASCII текст, байты объекты на самом деле ведут себя как неизменяемые последовательности целых чисел, каждое значение в последовательности ограниченной таким образом, что 0 <= x < 256 [.]

[...]

Поскольку объекты байтов являются последовательности целых чисел (сродни кортежа) для объекта байт b, b[0] будет целое число, в то время как b[0:1] будет bytes объект длины 1. (Это контрастирует с текстовыми строками, где индексирование и нарезка будут вызывать строку длиной 1).

Смелый акцент мой. Обратите внимание, что индексирование строки является немного исключением среди типов последовательностей; 'abc'[0] дает вам str объект длиной один; str - это единственный тип последовательности, который всегда содержит элементы своего типа.

Это повторяет, как другие языки обрабатывают строковые данные; в C unsigned char type также эффективно представляет собой целое число в диапазоне 0-255. Многие компиляторы C по умолчанию равны unsigned, если вы используете неквалифицированный тип char, а текст моделируется как массив char[].

+0

", в то время как b [0: 1] будет байтовым объектом длиной 1 (это контрастирует с текстовыми строками, где и индексирование, и нарезка произведут строку длины 1)« не могли бы вы объяснить это предложение, я не получил его? ? – CY5

+0

@ CY5: извините, какую часть вы получили?Если вы создаете строку (Unicode), '' abc '[0]' 'создает другой строковый объект' 'a''. Если вы используете тот же срез, что и пример, используемый для объекта 'bytes',' 'abc '[0: 1]' также создает строковый объект длиной один, '' a''. –

+0

@ CY5: но для объекта 'bytes'' b'abc '[0] 'производит целое число (' 97'), а срезание создает объект 'bytes' длиной один (' b'abc' [0: 1] 'производит' b'a''). –