chr() equivalent returning a bytes object, in py3k

25,762

Solution 1

Consider using bytearray((255,)) which works the same in Python2 and Python3. In both Python generations the resulting bytearray-object can be converted to a bytes(obj) which is an alias for a str() in Python2 and real bytes() in Python3.

# Python2
>>> x = bytearray((32,33))
>>> x
bytearray(b' !')
>>> bytes(x)
' !'

# Python3
>>> x = bytearray((32,33))
>>> x
bytearray(b' !')
>>> bytes(x)
b' !'

Solution 2

Try the following:

b = bytes([x])

For example:

>>> bytes([255])
b'\xff'

Solution 3

In case you want to write Python 2/3 compatible code, use six.int2byte

Solution 4

Yet another alternative (Python 3.5+):

>>> b'%c' % 65
b'A'

Solution 5

>>> import struct
>>> struct.pack('B', 10)
b'\n'
>>> import functools
>>> bchr = functools.partial(struct.pack, 'B')
>>> bchr(10)
b'\n'
Share:
25,762

Related videos on Youtube

zwol
Author by

zwol

If you want to know about me, please see my website: https://www.owlfolio.org/ . DO NOT CONTACT ME WITH ANY SORT OF JOB OFFER. The policy of treating comment threads as ephemeral and "not for extended discussion" is wrong, is actively harmful to the community, and I will not cooperate with it in any way. Using people's preferred pronouns is basic courtesy and it is reasonable for the code of conduct to insist on it. (I go by "he", for the record.)

Updated on April 12, 2020

Comments

  • zwol
    zwol about 4 years

    Python 2.x has chr(), which converts a number in the range 0-255 to a byte string with one character with that numeric value, and unichr(), which converts a number in the range 0-0x10FFFF to a Unicode string with one character with that Unicode codepoint. Python 3.x replaces unichr() with chr(), in keeping with its "Unicode strings are default" policy, but I can't find anything that does exactly what the old chr() did. The 2to3 utility (from 2.6) leaves chr calls alone, which is not right in general :(

    (This is for parsing and serializing a file format which is explicitly defined in terms of 8-bit bytes.)

  • zwol
    zwol over 13 years
    I get a little twitchy about throwing around scratch arrays but probably I shouldn't. It does the job, anyway.
  • malthe
    malthe about 11 years
    @Zack: You could use bytes((255, )) as a variation.
  • Guido U. Draheim
    Guido U. Draheim over 9 years
    bytes((255,)) in Python2 will NOT give you b'\xff' ... it returns '(255,)' instead.
  • jfs
    jfs almost 8 years
    @GuidoDraheim2013: it is Python 3 code i.e., don't use bytes([255]) on Python 2, use chr(255) there.
  • zwol
    zwol almost 8 years
    I don't see why that would be better than Guido's answer, particularly if I have no other need for six.
  • youfu
    youfu almost 8 years
    @zwol: For Python 3.2+, int2byte = operator.methodcaller("to_bytes", 1, "big"). According to the comment, this is about 2x faster than bytes((...)). Anyway, int2byte(x) looks better than bytes(bytearray((x,))) for me.
  • zwol
    zwol almost 8 years
    Speed is good, but in the thing that provoked the original question, no dependencies outside the standard library was an overriding concern.
  • Perkins
    Perkins over 7 years
    bytes takes a tuple for a constructor directly, so you can just use bytes((x,)). Only need to use bytearray if you want it to be mutable.
  • zwol
    zwol over 5 years
    Annoying that b'{:c}'.format(65) doesn't work as well, but thanks, this could be quite handy for the thing I originally wanted this for (and never got around to finishing).
  • martineau
    martineau over 5 years
    @malthe: bytes((255, )) is still creates a scratch array.