5

I have a bytes object, for instance

test = b'\x83\xf8\x41\x41\x41'

I would like to print this object to stdout, but if I do, Python converts the printable characters in the object to ASCII:

print(test)
b'\x83\xf8AAA'

Is there a way to force Python 3 to print the printable characters (in this instance, three 'A's) as escaped bytes?

That is, so that print(test) outputs

b'\x83\xf8\x41\x41\x41'

3 Answers3

5

No, the repr() output is not configurable; it is a debug tool.

You could use binascii.hexlify() to get a hex representation:

>>> test = b'\x83\xf8\x41\x41\x41'
>>> from binascii import hexlify
>>> test = b'\x83\xf8\x41\x41\x41'
>>> print(hexlify(test))
b'83f8414141'

or you could convert each individual 'byte' value to a hex representation:

>>> print("b'{}'".format(''.join('\\x{:02x}'.format(b) for b in test)))
b'\x83\xf8\x41\x41\x41'

This produces an alternative representation.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

You can create your own class for this:

class EscapeAll(bytes):
    def __str__(self):
        return 'b\'{}\''.format(''.join('\\x{:02x}'.format(b) for b in self))


# b'\x31\x32\x33'
print(EscapeAll(b'123'))
simonzack
  • 19,729
  • 13
  • 73
  • 118
1

Here's a way that's 30x ! faster (134 MiB/s on Intel i7-8700, Python2) than

''.join('\\x{:02x}'.format(b) for b in test)

It avoids iterating using slow, interpreted Python loops and iterates in optimized code. The optimized binascii also contributes to the speed

import binascii

hex=binascii.b2a_hex(test)
# add \x prefix
hex2=bytearray(4*len(b))
hex2[0::4]='\\'*len(b)
hex2[1::4]='x'*len(b)
hex2[2::4]=hex[0::2]
hex2[3::4]=hex[1::2]
Yale Zhang
  • 1,447
  • 12
  • 30
  • Seems to work in Python3 too, except the strings `'\\'` and `'x'` need to be bytes, so `b'\\'` and `b'x'`. Also, if we're being picky about speed, it might be worth putting `len(b)` in a variable :) – Warbo Aug 20 '21 at 08:35