type how first example documento collection _id python character-encoding ascii pyserial

python - first - mongodb how to use



Convertir un valor int a unicode (4)

Creo que la mejor solución es ser explícito y decir que quieres representar un número como un byte (y no como un carácter ):

>>> import struct >>> struct.pack(''B'', 128) >>> ''/x80''

Esto hace que su código funcione tanto en Python 2 como en Python 3 (en Python 3, el resultado es, como debería ser, un objeto de bytes ). Una alternativa, en Python 3, sería usar los nuevos bytes([128]) para crear un solo byte de valor 128.

No soy un gran fan de las soluciones chr() : en Python 3 , producen una cadena (de caracteres, no de bytes) que necesita ser codificada antes de enviarla a cualquier lugar (archivo, socket, terminal, ...) - chr() en Python 3 es equivalente a la problemática Python 2 unichr() de la pregunta. La solución de struct tiene la ventaja de producir correctamente un byte cualquiera que sea la versión de Python. Si desea enviar datos a través del puerto serie con chr() , debe tener control sobre la codificación que debe tener lugar posteriormente. El código podría funcionar cuando la codificación predeterminada utilizada por Python 3 es UTF-8 (que creo que es el caso), pero esto se debe al hecho de que los caracteres Unicode del punto de código menor a 256 se pueden codificar como un solo byte en UTF -8 Esto agrega una capa innecesaria de sutileza y complejidad que no recomiendo (hace que el código sea más difícil de entender y, si es necesario, de depuración).

Por lo tanto, le sugiero encarecidamente que utilice el enfoque anterior (que también fue mencionado por Steve Barnes y Martijn Pieters): deja claro que desea producir un byte (y no caracteres). No le dará ninguna sorpresa incluso si ejecuta su código con Python 3, y hace que su intento sea más claro y más obvio.

Estoy usando pyserial y necesito enviar algunos valores inferiores a 255. Si envío el int, el valor ascii del int se envía. Así que ahora estoy convirtiendo el int en un valor Unicode y lo envío a través del puerto serie.

unichr(numlessthan255); However it throws this error: ''ascii'' codec can''t encode character u''/x9a'' in position 24: ordinal not in range(128)

¿Cuál es la mejor manera de convertir un int a Unicode?


En Python 2: conviértelo primero en una cadena y luego en Unicode.

str(integer).decode("utf-8")

La mejor manera que pienso. Funciona con cualquier entero, y aún funciona si pones una cadena como entrada.

Edición actualizada debido a un comentario: para Python 2 y 3 - Esto funciona en ambos pero un poco desordenado:

str(integer).encode("utf-8").decode("utf-8")


Simplemente use chr(somenumber) para obtener un valor de 1 byte de un int siempre que sea menor que 256. pySerial lo enviará bien.

Si está pensando en enviar cosas a través de pySerial, es una muy buena idea mirar el módulo struct en la biblioteca estándar que maneja. Los problemas de empaquetado y endian, así como la codificación de casi todos los tipos de datos que probablemente necesite. 1 byte o más.


Utilice la función chr() lugar; está enviando un valor de menos de 256 pero más de 128, pero está creando un carácter Unicode.

El carácter Unicode se debe codificar primero para obtener un carácter de byte , y esa codificación falla porque está utilizando un valor fuera del rango ASCII (0-127):

>>> str(unichr(169)) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: ''ascii'' codec can''t encode character u''/xa9'' in position 0: ordinal not in range(128)

Este es el comportamiento normal de Python 2; cuando se intenta convertir una cadena Unicode en una cadena de bytes, debe tener lugar una codificación implícita y la codificación predeterminada es ASCII.

Si en su lugar utilizara chr() , creará una cadena de bytes de un carácter y no tendrá que tener lugar la codificación implícita:

>>> str(chr(169)) ''/xa9''

Otro método que quizás desee analizar es el módulo de struct , especialmente si necesita enviar valores enteros mayores a 255:

>>> struct.pack(''!H'', 1000) ''/x03/xe8''

El ejemplo anterior incluye un entero en un corto sin signo en orden de bytes de red, por ejemplo.