AttributeError: 'bytes' object has no attribute 'encode'

avatar
Borislav Hadzhiev

Last updated: Apr 8, 2024
4 min

banner

# AttributeError: 'bytes' object has no attribute 'encode'

The Python "AttributeError: 'bytes' object has no attribute 'encode'" occurs when we call the encode() method on a bytes object.

To solve the error, remove the call to the encode() method as the variable already stores a bytes object.

attributeerror bytes object has no attribute encode

Here is an example of how the error occurs.

main.py
my_str = 'bobbyhadz.com' my_bytes = my_str.encode('utf-8') print(type(my_bytes)) # ๐Ÿ‘‰๏ธ <class 'bytes'> # โ›”๏ธ AttributeError: 'bytes' object has no attribute 'encode'. Did you mean: 'decode'? result = my_bytes.encode('utf-8')

bytes object has no attribute encode

The issue in the code sample is that we are trying to encode a bytes object.

Encoding is the process of converting a string to a bytes object and decoding is the process of converting a bytes object to a string.

# You don't have to call the encode() method on bytes objects

To solve the error, remove the call to the encode() method.

main.py
my_str = 'bobbyhadz.com' print(type(my_str)) # ๐Ÿ‘‰๏ธ <class 'str'> my_bytes = my_str.encode('utf-8') print(type(my_bytes)) # ๐Ÿ‘‰๏ธ <class 'bytes'>

not calling encode method on bytes objects

The encode() method is used to convert a string to bytes, so the method cannot be called on a bytes object.

# Using a try/except statement to handle the error

If you aren't sure whether you have a bytes object or a string, use a try/except statement to handle the possible AttributeError.

main.py
my_str = 'bobbyhadz.com' print(type(my_str)) # ๐Ÿ‘‰๏ธ <class 'str'> try: encoded = my_str.encode('utf-8') print(encoded) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com' print(type(encoded)) # ๐Ÿ‘‰๏ธ <class 'bytes'> except AttributeError: pass

using try except statement to handle error

We try to encode the value and if it doesn't have an encode() attribute (it's not a string), we handle the AttributeError.

# Creating a reusable function that handles the error

You can also extract the logic into a reusable function.

main.py
def encode(string): try: encoded = string.encode('utf-8') return encoded except AttributeError: return string result = encode('bobbyhadz.com') print(result) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com' result = encode(b'bobbyhadz.com') print(result) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com'

create reusable function that handles the error

The function tries to encode the passed-in value to a bytes object and if an AttributeError is raised, the value is returned as is.

Encoding is the process of converting a string to a bytes object and decoding is the process of converting a bytes object to a string.

# Checking for the type of the variable before calling encode()

An alternative approach is to use an if statement to check for the type of the variable before you call the encode() method.

main.py
def encode(string): if isinstance(string, str): encoded = string.encode('utf-8') return encoded else: return string result = encode('bobbyhadz.com') print(result) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com' result = encode(b'bobbyhadz.com') print(result) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com'

check for type of variable before calling encode

The if statement checks if the supplied value has a type of string.

If the value is a string, we called the encode() method to convert the string to bytes.

Otherwise, we return the value as is.

# Using str.encode() vs bytes.decode()

You can use the str.encode() method to go from str to bytes and bytes.decode() to go from bytes to str.

main.py
my_text = 'bobbyhadz.com' my_binary_data = my_text.encode('utf-8') print(my_binary_data) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com' my_text_again = my_binary_data.decode('utf-8') print(my_text_again) # ๐Ÿ‘‰๏ธ 'bobbyhadz.com'

The str.encode() method is the opposite of bytes.decode() and returns a bytes representation of the Unicode string, encoded in the requested encoding.

# Using the bytes() and str() classes instead

You can also use bytes(s, encoding=...) and str(b, encoding=...).

main.py
my_text = 'bobbyhadz.com' my_binary_data = bytes(my_text, encoding='utf-8') print(my_binary_data) # ๐Ÿ‘‰๏ธ b'bobbyhadz.com' my_text_again = str(my_binary_data, encoding='utf-8') print(my_text_again) # ๐Ÿ‘‰๏ธ 'bobbyhadz.com'

The str() class returns a string version of the given object. If an object is not provided, the class returns an empty string.

The syntax for using the bytes() class is the same, except that a b prefix is added.

# Python 3 uses the concept of text and binary data

Ever since Python 3, the language uses the concepts of text and binary data instead of Unicode strings and 8-bit strings.

All text in Python is Unicode, however, encoded Unicode is represented as binary data.

You can use the str type to store text and the bytes type to store binary data.

In Python 3 you can no longer use u'...' literals for Unicode text because all strings are now Unicode.

However, you must use b'...' literals for binary data.

A good way to start debugging is to print(dir(your_object)) and see what attributes a string has.

# Checking what type a variable stores

If you aren't sure what type a variable stores, use the type() class.

main.py
my_str = 'bobbyhadz.com' print(type(my_str)) # ๐Ÿ‘‰๏ธ <class 'str'> print(isinstance(my_str, str)) # ๐Ÿ‘‰๏ธ True my_bytes = b'bobbyhadz.com' print(type(my_bytes)) # ๐Ÿ‘‰๏ธ <class 'bytes'> print(isinstance(my_bytes, bytes)) # ๐Ÿ‘‰๏ธ True

The type class returns the type of an object.

The isinstance() function returns True if the passed-in object is an instance or a subclass of the passed-in class.

# Printing the attributes of a bytes object

Here is an example of what printing the attributes of a bytes object looks like.

main.py
my_bytes = b'bobbyhadz.com' # ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'center', 'count', 'decode', 'endswith', 'expandtabs', 'find', 'fromhex', 'hex', 'index', 'isalnum', 'isalpha', 'isascii', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] print(dir(my_bytes))

If you pass a class to the dir() function, it returns a list of names of the class's attributes, and recursively of the attributes of its bases.

If you try to access any attribute that is not in this list, you will get the "AttributeError: bytes object has no attribute error".

Since encode() is not a method implemented by bytes objects, the error is caused.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev