Байты всегда октеты в Python?

Может ли быть реализация Python, в которой утверждение не выполняется:

assert all(byte in range(256) for byte in any_bytes_object) # Python 3 semantics 
assert all(byte in range(256) for byte in map(ord, any_bytes_object)) # Python 2

POSIX явно указывает, что CHAR_BIT == 8 (8 бит на байт). Есть ли аналогичная гарантия в Python? Это где-то задокументировано?

Справочник по Python 2 гласит: "Символы представляют (не менее ) 8-битные байты."

Если имя bytes не определено (в старых версиях Python), например, в Jython 2.5, тогда вопрос касается типа str (строки байтов), то есть bytes = str в Python 2.


person jfs    schedule 28.03.2016    source источник
comment
Я собирался придираться (str не является байтом в python3)... но потом я увидел, что это был ты... Я почти уверен, что ты это знаешь и действительно имеешь в виду объект байтов   -  person Joran Beasley    schedule 28.03.2016
comment
@JoranBeasley: я не вижу упоминания str в вопросе. Я обновил вопрос, чтобы показать примеры кода Python 3 и Python 2.   -  person jfs    schedule 28.03.2016
comment
В то время как в C термины char и byte в основном являются синонимами, POSIX изначально не делал заявлений о количестве битов в байте. Спецификация C99 окольным путем требовала, чтобы байт был 8-битным (путем построения бестолкового набора требований, единственным решением которого был 8-битный байт, без фактического указания этого явно), и поэтому Open Group в современном POSIX стандарты (с 2001 г. по настоящее время) требуют, чтобы байты были 8-битными (обоснование здесь: pubs. opengroup.org/onlinepubs/009695399/xrat/xbd_chap03.html). При всем при этом справочник по языку Python требует, чтобы байты были 8-битными.   -  person Nick Bastin    schedule 28.03.2016
comment
@NickBastin: 1- Я не вижу, где ссылка на язык Python (Python 2) требует, чтобы байты были точно 8-битными. Спецификация Python 2 говорит по крайней мере 2- я не понимаю, как это относится к этому вопросу, почему POSIX выбрал CHAR_BIT == 8 (sizeof(char) == 1, т.е. char здесь байт) 3- В принципе, определение Python того, что такое byte, может отличаться от определения byte, используемого другими частями системы, такой как JVM, компилятор C, CPU. Хотя на практике они совпадают.   -  person jfs    schedule 28.03.2016
comment
@J.F.Sebastian: спецификация Python для 3.6 говорит ровно 8 бит: docs.python.org/3.6/reference/ Также актуален вопрос POSIX, поскольку в вашем вопросе неявно утверждается, что CHAR_BIT является байтом (когда вы говорите 8 bits per byte), но это неверно. CHAR_BIT и байт не имеют указанных отношение.   -  person Nick Bastin    schedule 28.03.2016
comment
@NickBastin 1- мой вопрос не ограничивается Python 3, например, реализации Python 2, такие как jython, pypy, упоминаются явно 2- как вы думаете, возможно ли, что количество битов в байте отличается от CHAR_BIT?   -  person jfs    schedule 28.03.2016
comment
@ J.F.Sebastian: Да, есть абсолютно платформы, где количество битов в символе не равно количеству битов в байте (потому что символы с большей вероятностью перемещаются по сети, и должно быть соглашение, в котором даже говорится, что платформы DSP со странными размеры байтов будут учитываться в компиляторе для char - при условии, что современные цепочки инструментов были обновлены для соответствия C99, что в целом верно сейчас, но не сказать, что даже 5 лет назад).   -  person Nick Bastin    schedule 28.03.2016
comment
@NickBastin сеть определяется (обычно) с точки зрения октетов (не байтов, не символов). Я понимаю платформу DSP, где CHAR_BIT != 8, но sizeof(char) == 1, то есть количество битов в символе в любом случае равно количеству битов в байте. Вы говорите, что есть платформы, где sizeof(char)!=1?   -  person jfs    schedule 28.03.2016
comment
@ J.F.Sebastian: Во-первых, CHAR_BIT всегда равно 8, потому что так говорит стандарт. Но также sizeof char == 1 всегда, потому что стандарт также делает это требованием (задолго до C99), независимо от реализации (базовая реализация может делать все, что хочет, но компилятор должен сообщить, что sizeof char равно 1 ). Я хочу сказать, что ни один из этих типов не может быть байтом с точки зрения вашей архитектуры. (по какой-то причине не удалось перейти в чат, поэтому пишу здесь)   -  person Nick Bastin    schedule 29.03.2016
comment
@NickBastin 1- неправильно. CHAR_BIT не всегда 8 2- да, sizeof(char)==1 (упоминаю это в третий раз) и поэтому char здесь байт ( как я уже говорил). Вы не смогли привести пример, когда char не является байтом.   -  person jfs    schedule 29.03.2016
comment
@J.F.Sebastian: CHAR_BIT согласно спецификации POSIX должен быть равен 8. Если это не 8, то он не соответствует POSIX. Это, конечно, возможно, но здесь это не рассматривается. Кроме того, просто потому, что sizeof char == 1 не означает, что это байт, и это не означает, что единицей хранения для char на самом деле является CHAR_BIT (она просто должна выглядеть таковой, не требуется, чтобы он фактически был CHAR_BIT внутренне). Я действительно не знаю, что вы пытаетесь сказать здесь - моя единственная точка зрения заключается в том, что CHAR_BIT не имеет предсказуемой связи с размером байта архитектуры.   -  person Nick Bastin    schedule 29.03.2016
comment
@NickBastin 1- Вы знаете, что я знаю, что POSIX указывает CHAR_BIT == 8 - это прямо сказано в вопросе. POSIX в моем вопросе является примером спецификации, которая явно определяет значение CHAR_BIT. Это не означает, что сам вопрос ограничивается POSIX. Я согласен с тем, что эти комментарии выходят за рамки — как я сказал в ответ на ваш самый первый комментарий: я не понимаю, как это обсуждение относится к вопросу. 2- Я нашел явную ссылку в c99: Байт содержит CHAR_BIT битов, что является утверждением в вопросе: CHAR_BIT==8 подразумевает 8-битные байты.   -  person jfs    schedule 29.03.2016
comment
@ J.F.Sebastian: Как я сказал в своем втором комментарии и повторюсь сейчас, моя единственная проблема связана с этим утверждением в вашем вопросе: POSIX явно указывает, что CHAR_BIT == 8 (8 бит на байт). Это означает, что POSIX указывает CHAR_BIT как byte и это неверно.   -  person Nick Bastin    schedule 29.03.2016
comment
@NickBastin: это обсуждение никуда не годится. Что это вообще значит: POSIX определяет CHAR_BIT как байт. Стандарт C указывает, что CHAR_BIT - это количество битов в байте, поэтому POSIX также указывает его. POSIX (вдобавок) указывает, что CHAR_BIT == 8 и POSIX также явно говорит: >CHAR_BIT Количество битов в типе char. Как бы вы его ни нарезали: количество битов в байте равно количеству битов в char.   -  person jfs    schedule 29.03.2016
comment
@ J.F.Sebastian: Нет, это не так! Количество битов в байте в данной архитектуре зависит от архитектуры! Количество битов в символе всегда равно 8. Биты в char != биты в байте для многих архитектур.   -  person Nick Bastin    schedule 29.03.2016
comment
@NickBastin: я задал отдельный вопрос (с самостоятельным ответом): количество битов в байте равно количеству бит в типе char?   -  person jfs    schedule 29.03.2016


Ответы (3)


Объект bytes документация Python 3 говорит

объекты bytes на самом деле ведут себя как неизменяемые последовательности целых чисел, причем каждое значение в последовательности ограничено таким образом, что 0 ‹= x ‹ 256

И тип bytearray задокументирован как в Python 3, так и в Python 2 как

изменяемая последовательность целых чисел в диапазоне 0 ‹= x ‹ 256

поэтому язык разработан с учетом 8-битных байтов.


Раздел модели данных Python 2, в котором говорится, что «по крайней мере» 8 бит, кажется, является просто одним из мест, где документация Python 2 не очень хорошо обновляется по сравнению с документацией Python 3. Он восходит как минимум к Python 1.4, еще в самом в первые дни, когда они не были уверены, захотят ли они поддерживать странные размеры байтов.

По крайней мере, с момента введения поддержки Unicode в выпуске 2.0 документация была полна мест, в которых тип bytestring упоминается как «8-битные строки». Python не так строго определен, как что-то вроде C, но я бы сказал, что любая «соответствующая» реализация Python 2.0 или выше должна иметь 8-битные байты.

person user2357112 supports Monica    schedule 28.03.2016
comment
Не могли бы вы прокомментировать хотя бы часть ссылки на Python 2? - person jfs; 29.03.2016
comment
@ J.F.Sebastian: Я бы сказал, что они просто никогда не удосужились изменить документы Python 2. Он по крайней мере так же стар, как документация 1.4. Есть много мест, где документация по Python 2 не обновлялась так же, как и документация по Python 3. Во многих других местах в документации по Python 2 говорится о 8-битных строках, по-видимому, потому, что им внезапно пришлось отделять их от строк Unicode, когда в версии 2.0 появилась поддержка Unicode. - person user2357112 supports Monica; 30.03.2016
comment
Python не так строго определен, как язык C, но я бы сказал, что любая соответствующая реализация Python версии 2.0 или выше должна иметь 8-битные строки байтов. - person user2357112 supports Monica; 30.03.2016
comment
Да, 8-бит применяется в CPython с 2003 года (по крайней мере). Документы Python 3 формализуют это. В любом другом месте документации Python 2 упоминаются только 8-битные строки. Я не знаю ни одной реализации Python 2, которая не использует 8-битные строки; поэтому ответ таков: байты всегда являются октетами в Python. Не могли бы вы включить свой комментарий в ответ. - person jfs; 03.04.2016
comment
@ J.F.Sebastian: мои комментарии были включены в ответ. - person user2357112 supports Monica; 03.04.2016

В дополнение к официальной документации, цитируемой пользователем 2357112, мы можем ознакомиться с предложениями по усовершенствованию Python, которые представили объект bytes.

PEP 358 – указанный объект "bytes":

Объект bytes хранит изменяемую последовательность целых чисел в диапазоне от 0 до 255.

Поскольку мы знаем, что объекты bytes оказались неизменяемыми, эта спецификация не может быть полностью применима, а ее "диапазон" может быть спорным, слишком.

Интересно, что PEP 3137 -- неизменяемые байты и изменяемый буфер, который частично заменил PEP 358 (и определяет байты как неизменяемые и вводит bytearrays как изменяемый эквивалент) указывает только то, что вы можете поместить в объекты bytes и в bytearrays ( "int[eger]s in range(256)"), но не то, что из них может выйти.

Ни в одном PEP вообще не упоминаются «биты» или «биты». (Хотя из побитовых логических операций мы знаем, как целые числа Python отображаются в битовые шаблоны, поэтому, надеюсь, здесь не должно быть никаких сюрпризов.)

person das-g    schedule 28.03.2016
comment
docs.python.org/3.6/reference/ В разделе неизменяемых последовательностей явно указано, что байты являются 8-битными. - person Nick Bastin; 28.03.2016
comment
@NickBastin Хорошая находка. Вероятно, это должен быть правильный ответ, цитирующий соответствующий раздел этой страницы! - person das-g; 28.03.2016
comment
@das-g: bytes - это неизменяемая последовательность в Python, и поэтому PEP 358, который говорит иначе, не может использоваться в качестве ссылки. - person jfs; 28.03.2016
comment
@J.F.Sebastian о (не)изменяемости: Вы правы. Я отредактировал вопрос, чтобы учесть это. - person das-g; 28.03.2016
comment
Re Это, вероятно, должно быть ответом на его собственное право [...]: поскольку @NickBastin еще не опубликовал его, я попытался поместить это в Вики-ответ сообщества. Не стесняйтесь вносить свой вклад. :-) - person das-g; 28.03.2016

Питон 3

Начиная с Python 3.0 в справочнике по языку Python указано:

Объект bytes представляет собой неизменяемый массив. Элементы представляют собой 8-битные байты, представленные целыми числами в диапазоне 0 ‹= x ‹ 256.

Питон 2

До этого (т. е. до Python 2.7) он указывал (как уже упоминалось в вопросе):

Элементами строки являются символы. [] Символы представляют собой (как минимум) 8-битные байты.

(Выделение добавлено.)

Обратите внимание, что в Python 2 не было объекта bytes. Для хранения неизменяемых последовательностей двоичных данных, разделенных на байты, в Python 2 обычно использовались/используются строки. (Напротив, строки Python 3 предназначены только для текстовых данных и более эквивалентны объектам unicode Python 2, чем строкам Python 2.)

но ...

В документации Python 2 для ord() function упоминаются "8-битные строки" и противопоставляет их объектам Unicode. Может подразумеваться, что все строки Python-2, не поддерживающие юникод, являются 8-битными строками, но я бы на это не рассчитывал.

Вывод

Реализация Python, предоставляющая объекты bytes, совместимые с Python-3, будет ограничена тем, что в них будут храниться только 8-битные байты. Реализация Python, совместимая с Python 2, не будет связана с этим (поскольку объект bytes, если он есть, будет неуказанным), и если бы вы использовали его строки, совместимые с Python-2, в качестве замены, не было бы любые гарантии относительно максимального размера байта (на самом деле, размера символа), если только реализация не устанавливает некоторые собственные гарантии.

person Community    schedule 28.03.2016
comment
bytes is str на Python 2. Если bytes не определено (старые версии Python), то вопрос касается типа str (строки байтов). - person jfs; 28.03.2016