Asked By – A. Wilcox
I have code that expects
str but will handle the case of being passed
bytes in the following way:
if isinstance(data, bytes): data = data.decode()
Unfortunately, this does not work in the case of
bytearray. Is there a more generic way to test whether an object is either
bytearray, or should I just check for both? Is
hasattr('decode') as bad as I feel it would be?
Now we will see solution for issue: What is the proper way to determine if an object is a bytes-like object in Python?
There are a few approaches you could use here.
Since Python is duck typed, you could simply do as follows (which seems to be the way usually suggested):
try: data = data.decode() except (UnicodeDecodeError, AttributeError): pass
You could use
hasattr as you describe, however, and it’d probably be fine. This is, of course, assuming the
.decode() method for the given object returns a string, and has no nasty side effects.
I personally recommend either the exception or
hasattr method, but whatever you use is up to you.
This approach is uncommon, but is possible:
data = str(data, "utf-8")
Other encodings are permissible, just like with the buffer protocol’s
.decode(). You can also pass a third parameter to specify error handling.
Single-dispatch generic functions (Python 3.4+)
Python 3.4 and above include a nifty feature called single-dispatch generic functions, via functools.singledispatch. This is a bit more verbose, but it’s also more explicit:
def func(data): # This is the generic implementation data = data.decode() ... @func.register(str) def _(data): # data will already be a string ...
You could also make special handlers for
bytes objects if you so chose.
Beware: single-dispatch functions only work on the first argument! This is an intentional feature, see PEP 433.
This question is answered By – Elizafox
This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0