AttributeError: 'str' object has no attribute 'keys'

avatar

Borislav Hadzhiev

Wed Apr 20 20222 min read

AttributeError: 'str' object has no attribute 'keys' #

The Python "AttributeError: 'str' object has no attribute 'keys'" occurs when we try to call the keys() method on a string instead of a dictionary. To solve the error, make sure to parse the string if you have a JSON string or correct the assignment and call keys() on a dict.

attributeerror str object has no attribute keys

Here is an example of how the error occurs.

main.py
# 👇️ this is a string my_dict = '{"name": "Alice", "age": 30}' # ⛔️ AttributeError: 'str' object has no attribute 'keys' print(my_dict.keys())

We tried to call the keys() method on a string and got the error.

If you have a JSON string, use the json.loads() method to parse it into a native Python dictionary.

main.py
import json my_json_str = '{"name": "Alice", "age": 30}' # 👇️ parse JSON string to native Python dict parsed = json.loads(my_json_str) print(parsed.keys()) # 👉️ dict_keys(['name', 'age'])

We used the json.loads() method to parse the JSON string into a Python dictionary before calling the keys() method.

If you need to check if the value is a dictionary before calling the keys() method, use the isinstance function.

main.py
my_dict = {'name': 'Alice', 'age': 30} if isinstance(my_dict, dict): # 👇️ dict_keys(['name', 'age']) print(my_dict.keys())

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

Make sure you aren't calling the json.dumps() method on your dictionary as that would convert it to a JSON string.

main.py
import json my_dict = {"name": "Alice", "age": 30} print(type(my_dict)) # 👉️ <class 'dict'> # 👇️ json.dumps() converts a Python object to JSON string json_str = json.dumps(my_dict) print(type(json_str)) # 👉️ <class 'str'>

The json.dumps method converts a Python object to a JSON formatted string.

If you have a JSON string and are trying to parse it into a native Python dictionary, use the json.loads() method.

main.py
import json json_str = r'{"name": "Alice", "age": 30}' my_dict = json.loads(json_str) print(type(my_dict)) # 👉️ <class 'dict'>

The json.loads method parses a JSON string into a native Python object.

If the data being parsed is not a valid JSON document, a JSONDecodeError is raised.

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

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

main.py
my_string = 'hello world' # [ 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', # 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', # 'islower', 'isnumeric', 'isprintable', '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_string))

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

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

Since keys() is not a method implemented by strings, the error is caused.

Use the search field on my Home Page to filter through my more than 1,000 articles.