Skip to main content

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

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:
# ⛔️ AttributeError: 'str' object has no attribute 'get'
# Cannot call .get() on a string object.
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

# ✅ Correct Usage: Variable holds a dictionary
user_profile = {
"username": "jdoe",
"email": "[email protected]",
"status": "active"
}

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

# ✅ Call .get() on the dictionary
username = user_profile.get("username")
print(f"Username: {username}") # Output: Username: jdoe

# ✅ Use .get() safely for potentially missing keys
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()")
# Handle the non-dictionary case appropriately

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'>

# ... some code ...

# ⚠️ Accidental reassignment (e.g., processing a message string)
status_message = "User updated successfully."
user_data = status_message # Overwrites the dictionary!

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

# ... later ...
try:
# ⛔️ AttributeError: 'str' object has no attribute 'get'
# user_data is now a string
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"}
}

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

# Trying to access status_message as if it were a dict fails
try:
# ⛔️ AttributeError: 'str' object has no attribute 'get'
# data.get('status_message') returns the STRING "Processing complete"
# Can not call .get() on that string.
detail = data.get("status_message").get("detail") # Error occurs here
print(detail)
except AttributeError as e:
print(e)

# ✅ Correct approach: Check the type of the retrieved value
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"

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

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

Do not confuse dictionary key access (.get() or []) with string character/substring access ([] with index or slice).

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']
note

The output NOT include .get.

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):
# Safe to call .get() here, likely a dict (or dict-like)
value = maybe_dict.get("some_key", "Default")
print(f"Value via hasattr: {value}")
else:
# Handle the case where it's not a dictionary
print(f"'{maybe_dict}' does not have a callable 'get' method.") # This runs

Output:

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

As with previous errors, hasattr prevents the crash but doesn't fix the underlying logic issue if you always expected a dictionary. Use it when polymorphism is intended or unavoidable.

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.