Преобразование значения int в unicode

Я использую pyserial и должен отправить некоторые значения меньше 255. Если я отправлю сам int, будет отправлено значение ascii int. Итак, теперь я преобразую int в значение unicode и отправляю его через последовательный порт.

unichr(numlessthan255);

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

каков наилучший способ преобразования int в unicode?

4 ответов


просто использовать chr(somenumber) чтобы получить значение 1 байта int, если оно меньше 256. затем pySerial отправит его в порядке.

Если вы смотрите на отправку вещей через pySerial, это очень хорошая идея, чтобы посмотреть на модуль struct в стандартной библиотеке он обрабатывает endian выдает проблемы с упаковкой, а также кодировку для почти каждого типа данных, который вам, вероятно, понадобится, это 1 байт или более.


в Python 2-Сначала превратите его в строку, а затем в unicode.

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

лучший способ я думаю. Работает с любым целым числом, плюс еще работает, если вы поместите строку в качестве входного.

Обновлено редактирование из-за комментария: для Python 2 и 3-это работает на обоих, но немного грязно:

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

использовать chr() функции вместо этого; вы отправляете значение меньше 256, но больше 128, но создаете символ Юникода.

символ Юникода должен быть закодирован сначала, чтобы получить байт символ, и эта кодировка терпит неудачу, потому что вы используете значение вне диапазона 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)

это нормальное поведение Python 2; при попытке преобразовать строку unicode в байтовую строку неявная кодировка должен иметь место и кодировка по умолчанию-ASCII.

если вы используете chr() вместо этого вы создаете байтовую строку из одного символа, и эта неявная кодировка делает не должны иметь место:

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

другой метод, который вы можете захотеть изучить, - это struct модуль, особенно, если вам нужно отправить целочисленные значения больше чем 255:

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

приведенный выше пример упаковывает целое число в беззнаковое короткое например, в сетевом порядке байтов.


Я думаю, что лучшее решение-быть явным и сказать, что вы хотите представить число в виде байта (и не как символ):

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

это заставляет ваш код работать как в Python 2, так и в Python 3 (в Python 3 результат, как и должно быть,байт