Когда вы набираете что-то вроде thing = b"\xb4"
, то, что хранится в Python, объект кода после компиляции - это просто фактическое число 0xb4 (180 в десятичном виде).Это не имеет никакого отношения к Юникоду вообще - фактически, разделение байтов и текстовых строк в Python 3 было сделано точно так, что значения байтов - это одно, а текст - другое, и для «привязки» нужно связать их сother.
Ваше значение будет таким же, как если бы вы сделали:
In [155]: thing = bytes([180])
In [156]: thing
Out[156]: b'\xb4'
Это становится символом в Python 3 только в случае преобразования в строку с помощью явной кодировки:
In [157]: print(thing.decode("latin1"))
´
Что происходит, так это то, что при некотором сходстве с самим языком Python 2 и C байтовые значения, которые оказываются отображенными в диапазон [32, 128], печатаются как символы ASCII.Итак, 0x75 соответствует символу ASCII u
- но внутреннее представление обоих чисел в my_thing = b'\xb4\x75'
по-прежнему представляет собой одно байтовое числовое значение для каждого - независимо от того, каково их представление с print
.И когда вы отправляете этот объект байтов в двоичном пакете, оба числа 0xb4 и 0x75 будут отправлены как числовые значения.
Это легко проверить, если вы итерируете байтовую строку, которая выдает числовые значения в диапазоне [0, 256], или записываете значения в файл и проверяете, что он на самом деле содержит только 2 байта.:
In [158]: my_thing = b"\xb4\x75"
In [159]: my_thing
Out[159]: b'\xb4u'
In [160]: list(my_thing)
Out[160]: [180, 117]
In [161]: open("test.bin", "wb").write(my_thing)
Out[161]: 2
In [162]: !ls -la test.bin
-rw-rw-r--. 1 gwidion gwidion 2 Jun 13 17:46 test.bin
(«2» в последней строке в этом листинге - это размер файла в байтах, указанный в «ls» оболочки Linux)
Итак, единственная проблемау вас есть, если таковые имеются, возможность визуализировать ваши значения на стороне Python, прежде чем они будут отправлены - для этой цели, а затем для просмотра значений в консоли хоста, либо в виде распечатки в TTY, либо в виде графического интерфейса пользователя, либоСгенерировав веб-страницу, вы делаете противоположную вещь, которую, как вы думаете, происходит: Вызовите метод, который дает вам текстовый объект, представляющий HEX-цифры вашего байтового объекта в виде текста - так, чтобы его можно было легко проверить.У самого объекта байтов есть метод .hex()
, который подходит для этой цели:
In [165]: my_thing.hex()
Out[165]: 'b475'
Итак, вот вам - шестнадцатеричные числа для 2 байтов, которые вы готовы отправить в виде пакета, рассматриваемые как текст - в то время каксодержимое самого my_thing
не изменяется.
Это не имеет префикса "\xYY"
, поэтому лучше смотреть - и, если вы введете много значений, есть также метод байтов, который преобразует каждую пару шестнадцатеричных цифрв байт - и это гораздо удобнее для ввода буквенных значений.bytes.fromhex
метод класса.Это позволяет вам набирать:
In [166]:my_thing = bytes.fromhex("b475")
И это эквивалентно b"\xb4\x75"
.
Если по какой-то причине вам действительно нужен префикс \x
для каждой пары цифр, однострочный код Python может манипулировать им для генерации строки, содержащей литерал байтовой строки, который может быть передан eval
, например - но использование bytes.fromhex
все равно будет более читабельным:
converter = lambda seq: 'b"{}"'.format("".join(f"\\x{value:x}" for value in seq))
А в интерактивном сеансе:
In [168]: my_thing = b"\xb4\x75"
...:
...: converter = lambda seq: 'b"{}"'.format("".join(f"\\x{value:x}" for value in seq))
...: print(converter(my_thing))
b"\xb4\x75"
Это всего лишь распечатка текстовой строки- последовательность текстовых символов, включая символы «b», «» и т. д. Для возврата байтовых букв необходимо применить eval:
In [169]: eval(converter(my_thing))
Out[169]: b'\xb4u'