Skip to content

How to Resolve Python "AttributeError: 'str' object has no attribute 'get'"

Fix the Python AttributeError when calling .get() on a string by verifying the variable is a dictionary, checking nested data types, and using proper string indexing instead.

The AttributeError: 'str' object has no attribute 'get' is a common Python error indicating a fundamental misunderstanding between data types. It occurs when you try to use the .get() method, which is specifically designed for dictionaries to safely retrieve values by key, on a variable that actually holds a string (str).

This guide explains why strings don't have a .get() method and provides clear solutions to fix this error by ensuring you're working with the correct data type.

Understanding the Error: .get() is for Dictionaries

In Python, the .get(key, default=None) method is a core feature of dictionaries (dict). It allows you to retrieve the value associated with a specific key. Its main advantage over bracket notation (my_dict['key']) is that it doesn't raise a KeyError if the key is missing; instead, it returns None or a specified default value.

Strings (str), being sequences of characters, do not operate on a key-value basis and therefore do not have a .get() method. Trying to call .get() on a string results in the AttributeError.

The Cause: Calling .get() on a String Variable

The error occurs simply because the variable you are calling .get() on holds a string value at that point in your code execution.

my_variable = "This is a string, not a dict"

print(f"Type of my_variable: {type(my_variable)}") # Output: <class 'str'>

try:
    value = my_variable.get("some_key")
    print(value)
except AttributeError as e:
    print(e)

Solution 1: Ensure the Variable is a Dictionary

The primary solution is to make sure the variable you intend to use .get() on actually refers to a dictionary object.

Correct Usage with a Dictionary

user_profile = {
    "username": "jdoe",
    "email": "john.doe@example.com",
    "status": "active"
}

print(f"Type of user_profile: {type(user_profile)}")     # Output: <class 'dict'>

username = user_profile.get("username")
print(f"Username: {username}")                           # Output: Username: jdoe

location = user_profile.get("location", "Not specified") # Key missing
print(f"Location: {location}")                           # Output: Location: Not specified

Checking Type with isinstance()

Before calling .get(), especially if a variable might hold different types, you can explicitly check if it's a dictionary using isinstance().

maybe_dict = "Could be string" # Or maybe_dict = {'key': 'value'}

if isinstance(maybe_dict, dict):
    print("It's a dictionary, safe to use .get()")
    value = maybe_dict.get("some_key", "Default")
    print(f"Value from get: {value}")
else:
    print(f"It's NOT a dictionary (it's a {type(maybe_dict)}), cannot use .get()")

Common Scenarios Leading to the Error

How does a variable end up being a string when you expected a dictionary?

Accidental Reassignment to String

A variable might initially be a dictionary but gets overwritten with a string value later in the code.

user_data = {"id": 101, "prefs": {"theme": "dark"}}
print(f"Initial type: {type(user_data)}") # <class 'dict'>


status_message = "User updated successfully."
user_data = status_message # Overwrites the dictionary!

print(f"Type after reassignment: {type(user_data)}") # <class 'str'>

try:
    theme = user_data.get("prefs", {}).get("theme")
    print(theme)
except AttributeError as e:
    print(e)

Solution: Find and fix the incorrect reassignment. Use different variable names if necessary.

Working with Nested Data (Mixed Types)

Sometimes, a dictionary might contain values that are themselves strings, while other values are nested dictionaries. Trying to call .get() on a value that is actually a string will fail.

data = {
    "config": {"retries": 3, "timeout": 30},
    "status_message": "Processing complete", # This value is a string
    "user": {"id": 5, "name": "Eve"}
}

retries = data.get("config", {}).get("retries")
print(f"Retries: {retries}") # Output: Retries: 3

try:
    detail = data.get("status_message").get("detail") # Error occurs here
    print(detail)
except AttributeError as e:
    print(e)

status_val = data.get("status_message")
if isinstance(status_val, dict):
    detail = status_val.get("detail")
    print(f"Status detail: {detail}")
elif isinstance(status_val, str):
    print(f"Status is a string: '{status_val}'") # This is executed
else:
    print("Status has an unexpected type.")

Output:

Retries: 3
'str' object has no attribute 'get'
Status is a string: 'Processing complete'

Solution: Check the type of the value retrieved from the outer dictionary before attempting to call .get() on it.

Alternative: Accessing String Content (Indexing/Slicing)

If your variable is a string and you were trying to use .get() because you mistakenly thought it was a dictionary, but you actually wanted to access parts of the string, remember to use string indexing or slicing:

my_string = "Python"

first_char = my_string[0]
print(f"First char: '{first_char}'") # Output: First char: 'P'

sub = my_string[1:4] # Characters at index 1, 2, 3
print(f"Substring: '{sub}'")         # Output: Substring: 'yth'

Debugging Steps

Check the Variable's Type (type())

The essential first step:

print(f"DEBUG: Type of my_variable is {type(my_variable)}")

If it's <class 'str'>, you know why .get() fails.

Check Available String Attributes/Methods (dir())

Confirm that .get is not a standard string method:

print(dir("any string"))

Output:

['__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', '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', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

Use hasattr() (Defensive Check)

You can check if an object has a .get method before calling it. This is useful if a variable might be a dictionary or something else.

maybe_dict = "hello" # Could be a string or dict

if hasattr(maybe_dict, 'get') and callable(maybe_dict.get):
    value = maybe_dict.get("some_key", "Default")
    print(f"Value via hasattr: {value}")
else:
    print(f"'{maybe_dict}' does not have a callable 'get' method.") # This runs

Output:

'hello' does not have a callable 'get' method.

Conclusion

The AttributeError: 'str' object has no attribute 'get' clearly signals that you are attempting to use the dictionary-specific .get() method on a string variable.

The primary solutions are:

  1. Verify the variable is a dictionary: Ensure the variable holds a dict before calling .get(). Use isinstance(var, dict) for checks.
  2. Correct the variable's value: Trace back and fix where the variable was incorrectly assigned a string value instead of the intended dictionary.
  3. Handle nested data carefully: Check the type of values retrieved from dictionaries before assuming they are also dictionaries and calling .get() on them.
  4. Use appropriate string indexing/slicing if your intent was actually to access parts of the string content.

Remembering that .get() is exclusively for dictionaries (and dictionary-like objects) is key to avoiding and resolving this error.

Navigation