Преобразование байтовой строки в Micropython

Как отмечено здесь, получение сообщения через сокет Micropython приводит к тому, что остается строка байтов для работы. Мой вопрос: как преобразовать эту строку байтов в другой пригодный для использования формат?

Я пробовал подобные:

data = s.recv(64)
new = hex(data)

что приводит к таким ошибкам, как:

TypeError: невозможно преобразовать байты в int

И: data = s.recv(64).hex() Результат:

AttributeError: объект «bytes» не имеет атрибута «hex»

Я довольно новичок в Python и Micro-python в целом. Насколько я могу судить, на этот вопрос не было дано прямого ответа для Micropython.

Если на этот вопрос был дан ответ специально для Python3, я думаю, что стоит повторить его для Micropython, поскольку реализация может немного отличаться и, возможно, найти приемлемую «лучшую практику».


person goldfishalpha    schedule 06.03.2019    source источник


Ответы (5)


Не совсем понятно, что вы пытаетесь сделать.

Вы конвертируете байты в строку, вызывая метод .decode. Это дает вам байты:

data = s.recv(64)

И это преобразует это в строку:

data = data.decode('utf-8')

Но вы пытаетесь вызвать hex(), который принимает одно целое число и возвращает соответствующее шестнадцатеричное значение. В контексте вашего вопроса это не имеет особого смысла.

person larsks    schedule 06.03.2019
comment
@larsks Спасибо, я пытался добиться одной или обеих двух вещей: 1. Чтобы сделать данные пригодными для использования (операторы if и т. д.), 2. вызов 'hex() должен был "преобразовать" входящие данные в шестнадцатеричный формат. чтобы он мог отображаться как таковой при печати. Очевидно, мне не хватает знаний о типах данных. - person goldfishalpha; 07.03.2019

Вы пробовали import struct?

new = struct.unpack('=i', data)
person phil    schedule 11.03.2019
comment
Для меня это было struct.unpack('i', data) - person multipolygon; 06.12.2019

Итак, у вас есть объект bytes, и похоже, что вам нужна строка, содержащая шестнадцатеричное представление этих байтов.

Ответы на вопрос описывает, как это сделать в стандартном Python, но из быстрой проверки с помощью онлайн-консоли MicroPython вы не можете просто вызвать .hex() для самого объекта bytes, и у нас нет модулей binascii или codecs, поэтому ни один из этих методов не будет работать.

Однако нетрудно делать то, что вы хотите, с помощью простого Python:

>>> data = b'hello!'
>>> ''.join(['{:02x}'.format(b) for b in data])
'68656c6c6f'

Здесь мы используем понимание списка, чтобы получить каждый байт b по очереди из объекта bytes data. Затем мы форматируем это в двухсимвольную строку в шестнадцатеричном формате с начальным нулем, если необходимо, используя '{:02x}'.format(b). Выражение в квадратных скобках дает нам список этих двухсимвольных строк, поэтому, наконец, мы join объединяем их вместе, разделяя пустой строкой.

Например, если вам нужен пробел между каждой группой из двух цифр, замените '' на ' '.

Я считаю это полезной отправной точкой для методов форматирования строк в Python. MicroPython поддерживает методы %-operator и str.format, но не форматированные строковые литералы.

person nekomatic    schedule 08.03.2019
comment
На самом деле существует модуль ubinascii, который содержит функции hexlify и unhexlify и может быть импортирован как «ubinascii» или просто «binascii»: https://docs.micropython.org/en/latest/library/ubinascii..html - person birdistheword99; 10.06.2020

Хотя я думаю, что ответ @larsks лучший (вызов .deocde()), вы изначально сказали, что хотите его в шестнадцатеричном формате.

Стоит отметить, что модуль ubinascii доступен на большинстве портов micropython и имеет функцию «hexlify» для преобразования в шестнадцатеричный формат. Однако он по-прежнему будет возвращать строку байтов, поэтому вам может потребоваться вызвать .decode() в зависимости от вашей предполагаемой цели: https://docs.micropython.org/en/latest/library/ubinascii.html

Вы также можете взглянуть на встроенный метод класса from_bytes, встроенный в тип int. Вы можете использовать его с:

x = int.from_bytes(byte_string, byte_order)

https://docs.micropython.org/en/latest/library/builtins.html?highlight=to_bytes

person birdistheword99    schedule 10.06.2020

Мне нужно было преобразовать байтовый MAC-адрес в строку, представляющую шестнадцатеричные значения. @birdistheword99 показал мне путь...

MAC-адрес, полученный из системы, выглядит так: b'\xacg\xb27-\xcc'. Это не очень удобно для читателя. Чтобы превратить его в строку шестнадцатеричных цифр...

import binascii

mac_bytes = b'\xacg\xb27-\xcc'
mac_str = binascii.hexlify(mac_bytes).decode()
print(mac_str)

Урожайность...

ac67b2372dcc
person stanely    schedule 24.03.2021