AttributeError: ‘str’ object has no attribute ‘decode’ (Fixed)

Picture of person's hands, holding a magnifier in the left hand, and a pen in the right hand. He's trying to decipher a code.
Photo by cottonbro studio, source: Pexels

AttributeError: ‘str’ object has no attribute ‘decode’

If you’re getting the “AttributeError: ‘str’ object has no attribute ‘decode’ error, you’re probably calling decode() on a string object (str) in Python 3.

Here’s what the error message looks like in the Python shell:


>>> username = 'admin'
>>> username.decode()
Traceback (most recent call last):
 File "", line 1, in 
AttributeError: 'str' object has no attribute 'decode'. Did you mean: 'encode'?
>>>

Python 3 stores a string as a sequence of Unicode code points and hence there's no need to decode them.

The new str class doesn't even implement the decode() method. If you call this method on a Python 3 string, you'll get the infamous "AttributeError: 'str' object has no attribute 'decode'" error.

Let's confirm it by calling the hasattr() function:


username = 'admin'
hasattr(username, 'decode') # False

As you can see, the hasattr() function returns False in this case.

It wasn't the case with Python 2, though. In Python 2, you can store strings as:

  • 8-bit strings (by default)
  • Unicode objects - by using the u prefix before a string literal (e.g., u'somestring') or by using the unicode constructor (unicode('somestring'))

In Python 2, 8-bit strings and Unicode objects expose a decode() method to convert the passed value into a Unicode object.

In Python 3, however, you don't have to decode a string as it's already decoded to Unicode.

Encoding and Decoding in Python 3

In Python 3, you can only call the decode() method on a bytes object - when you want to decode it into a Unicode string.

In the Python 3 context: 

  • Encoding is the process of converting a str object to a bytes object
  • Decoding is the process of converting a bytes object to a str object based on the specified encoding.

I like this creative diagram from a user on StackOverflow:

┏━━━━━━━┓                ┏━━━━━━━┓
┃       ┃ -> encoding -> ┃       ┃
┃  str  ┃                ┃ bytes ┃
┃       ┃ <- decoding <- ┃       ┃
┗━━━━━━━┛                ┗━━━━━━━┛

Calling encode() on a string returns a bytes object:


username = 'admin'
username_encoded = username.encode()

print(type(username_encoded)) # <class 'bytes'>
print(hasattr(username_encoded, 'decode')) # True
print(username_encoded) # b'admin'

If you're working with a legacy code and have no control over the value (whether it's a bytes or str object), you can use a try/catch block to avoid a possible attribute error.


try:
    username_decoded = username.decode('UTF-8')
    # Do something here
except AttributeError:
    pass

But as mentioned earlier, you don't usually need to decode your Python string to Unicode as it already is.

And that's how you fix the "AttributeError: 'str' object has no attribute 'decode'" error in Python 3.

I hope that solves your problem. Thanks for reading.

Author photo

Hey πŸ‘‹ I'm a software engineer, an author, and an open-source contributor. I enjoy helping people (including myself) decode the complex side of technology. I share my findings on Twitter: @lavary_

If you read this far, you can tweet to the author to show them you care. Tweet a Thanks

In this article:

Disclaimer: This post might contain affiliate links. I might receive a commission if a purchase is made. However, it doesn’t change the cost you’ll pay.