parse library data array python integer endianness

data - struct python library



Endianness de enteros en Python (4)

Estoy trabajando en un programa donde almaceno algunos datos en un entero y lo proceso en bits. Por ejemplo, podría recibir el número 48, que procesaré bit a bit. En general, la endianidad de los enteros depende de la representación de la máquina de los enteros, pero ¿Python hace algo para garantizar que los ints siempre serán little-endian? ¿O necesito verificar endianness como lo haría en C y luego escribir un código separado para los dos casos?

Lo pregunto porque mi código se ejecuta en una máquina Sun y, aunque la que se está ejecutando ahora usa procesadores Intel, es posible que tenga que cambiar a una máquina con procesadores Sun en el futuro, que sé que es un gran habitante.


Comprobar cuando?

Al realizar operaciones en modo bit, la int en tendrá la misma endianess que las entradas que pones. No es necesario que lo verifiques. Solo necesita importar esto al convertir a / desde secuencias de bytes, en ambos idiomas, afaik.

En Python utiliza el módulo struct para esto, comúnmente struct.pack () y struct.unpack ().


El siguiente fragmento le dirá si su sistema predeterminado es little endian (de lo contrario, es big-endian)

import struct little_endian = (struct.unpack(''<I'', struct.pack(''=I'', 1))[0] == 1)

Sin embargo, tenga en cuenta que esto no afectará el comportamiento de los operadores bit a bit: 1<<1 es igual a 2 independientemente de la endianidad predeterminada de su sistema.


Si necesita procesar sus datos ''bitwise'', entonces el módulo de bitstring podría serle útil. También puede tratar con endianness entre plataformas (al menos en la última construcción de troncales, que se lanzará en los próximos días).

El módulo struct es el mejor método estándar para lidiar con la endianidad entre plataformas. Por ejemplo, esto empaqueta y descomprime los enteros 1, 2, 3 en dos ''cortos'' y uno ''largo'' (2 y 4 bytes en la mayoría de las plataformas) usando endianness nativo:

>>> from struct import * >>> pack(''hhl'', 1, 2, 3) ''/x00/x01/x00/x02/x00/x00/x00/x03'' >>> unpack(''hhl'', ''/x00/x01/x00/x02/x00/x00/x00/x03'') (1, 2, 3)

Para comprobar el endianness de la plataforma mediante programación, puede usar

>>> import sys >>> sys.byteorder

que volverá "big" o "little" .


El int de Python tiene el mismo endianness que el procesador en el que se ejecuta. El módulo struct permite convertir blobs de bytes a ints (y viceversa, y algunos otros tipos de datos también) en formas nativas, little-endian o big-endian, dependiendo de la cadena de formato que elija: inicie el formato con @ o sin carácter endianness para usar endianness nativo (y tamaños nativos - todo lo demás usa tamaños estándar), ''~'' para native, ''<'' para little-endian, ''>'' o ''!'' para big-endian.

Esto es byte a byte, no bit a bit; no estoy seguro de lo que quiere decir con el procesamiento bit por bit en este contexto, pero supongo que puede ser acomodado de manera similar.

Para un procesamiento "masivo" rápido en casos simples, considere también el módulo de matriz : los métodos de tostring fromstring y tostring pueden operar en gran cantidad de bytes rápidamente, y el método de byteswap de bytes puede obtener la "otra" endianidad (nativa a no nativa o viceversa), de nuevo rápidamente y para un gran número de elementos (toda la matriz).