chr() equivalent returning a bytes object, in py3k
Question:
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.)
Answers:
Try the following:
b = bytes([x])
For example:
>>> bytes([255])
b'xff'
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' !'
>>> import struct
>>> struct.pack('B', 10)
b'n'
>>> import functools
>>> bchr = functools.partial(struct.pack, 'B')
>>> bchr(10)
b'n'
In case you want to write Python 2/3 compatible code, use six.int2byte
Yet another alternative (Python 3.5+):
>>> b'%c' % 65
b'A'
simple replacement based on small range memoization (should work on 2 and 3), good performance on CPython and pypy
binchr = tuple([bytes(bytearray((b,))) for b in range(256)]).__getitem__
binchr(1) -> b'x01'
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.)
Try the following:
b = bytes([x])
For example:
>>> bytes([255])
b'xff'
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' !'
>>> import struct
>>> struct.pack('B', 10)
b'n'
>>> import functools
>>> bchr = functools.partial(struct.pack, 'B')
>>> bchr(10)
b'n'
In case you want to write Python 2/3 compatible code, use six.int2byte
Yet another alternative (Python 3.5+):
>>> b'%c' % 65
b'A'
simple replacement based on small range memoization (should work on 2 and 3), good performance on CPython and pypy
binchr = tuple([bytes(bytearray((b,))) for b in range(256)]).__getitem__
binchr(1) -> b'x01'