Your code calls a method on a variable, and Python replies with AttributeError: 'NoneType' object has no attribute 'something'. In plain terms, the variable you expected to hold an object actually holds None — Python’s “nothing here” value — and nothing has no methods. This error is rarely about the line that fails; it is about an earlier line where the value silently became None. This guide shows you the handful of ways None sneaks into variables and how to trace each one.
Quick Answer
The error means the variable before the dot holds None at the moment you call a method or read an attribute on it. Print the variable just above the failing line to confirm, then find why it is None: usually a function that forgot its return statement, a method like sort() or append() whose result you wrongly stored (those methods return None), or a lookup such as .get() or a search that found nothing.
The Usual Ways None Sneaks In
A function with no return statement
Every Python function returns something. If it reaches the end without a return, it returns None automatically. So when you write result = calculate_total(prices) and calculate_total only prints the total instead of returning it, result becomes None, and the crash arrives later when you use it. The fix is to return the value from the function and keep print for display only.
Storing the result of an in-place method
Some list methods modify the list in place and return None by design: sort(), append(), extend(), reverse(), and remove(). The classic trap is names = names.sort(), which sorts the list and then replaces your only reference to it with None. Call the method on its own line, and use sorted(names) when you want a new sorted list as a value. The official documentation on mutable sequence types notes which operations return None.
A search that found nothing
Many lookups return None on failure instead of raising an error: dictionary .get(key) without a default, regular expression .search() when there is no match, find()-style helpers in various libraries, and database queries for a missing row. If you immediately chain a method onto the result, such as match.group(1), a failed search becomes this AttributeError.
A variable initialised to None and never filled
Code often starts with user = None and assigns the real value inside an if. When the condition is false, the value stays None and later code crashes. This is the same family as the “defined only in a branch” trap behind many a NameError in beginner scripts, except the name exists and merely holds nothing.
How to Trace It Step by Step
- Identify the expression before the dot. In
result.strip(), the suspect isresult. The attribute name at the end of the error message tells you what you tried to call. - Print the variable and its type above the failing line.
print(result, type(result))showingNone <class 'NoneType'>confirms the diagnosis instantly. - Find every assignment to that variable. Search the file for the name. One of those assignments produced None: a function call, a method result, a
.get(), or a literal None. - Open the function or method involved. If the value came from your own function, check for a missing
return. If it came from a built-in or library method, check whether that method returns a new value or modifies in place. - Fix at the source, then remove the debug print. Resist the urge to patch the failing line alone; the bug lives where None was created.
Defensive Patterns That Help
Sometimes None is a legitimate answer, for example a search that may find nothing. Then handle it deliberately: test if match is not None: before using the result, or supply defaults with data.get("name", "Unknown"). Guard clauses near the top of a function, which return early when a required value is None, keep the main logic clean. What you should avoid is scattering unexplained if x: checks everywhere as a substitute for understanding where the None came from — that hides real bugs behind silence.
Common Mistakes to Avoid
- Writing
list = list.sort()orlist = list.append(x). In-place methods return None. Call them bare, or usesorted()when you need a value. - Printing inside a function instead of returning. A function that computes something should return it. Printing is for the part of the program that talks to the user.
- Chaining calls onto a search result.
pattern.search(text).group(0)is a crash waiting for unmatched input. Store the match, test it, then use it. - Comparing with
== Noneor truthiness alone. Useis Nonefor exactness; empty strings and zero are also “falsy” but are not None, and confusing them creates fresh bugs.
None Hiding in Dictionaries and JSON Data
Real programs feed heavily on dictionary-shaped data — settings files, API responses, JSON — and None breeds quietly there. A nested lookup like data["user"]["address"]["city"] works until one record lacks an address, at which point data["user"]["address"] is either missing or, in many APIs, literally present with the value null, which Python loads as None. The next attribute or key access then fails with this same AttributeError, or its KeyError cousin. The robust pattern is to fetch each level with .get() and a sensible default, or to test each level before descending: assign address = data.get("user", {}).get("address"), then check if address: before reading further. It reads a little longer than the chained version, but it degrades gracefully on the imperfect data that real systems produce, and when something is genuinely missing the failure becomes a controlled branch in your code instead of a crash with a puzzling message. Whenever you consume data you did not create, assume any field can be None until you have seen evidence otherwise.
Conclusion
'NoneType' object has no attribute means a variable you trusted actually holds nothing. Print it, trace its assignments, and check for the three classic sources: a function without return, an in-place method whose result you stored, or a search that found nothing. Fix the source, guard the cases where None is a legitimate answer, and this error becomes easy to read at a glance.
Frequently Asked Questions
Why does list.sort() return None on purpose?
It is a deliberate Python design choice: methods that modify an object in place return None so you cannot mistake them for methods that create a new object. It makes the mutation explicit in your code. When you want a sorted copy as a value, use the built-in sorted() function instead.
What is the difference between None and an empty string or zero?
None means the absence of a value. An empty string is a real string with no characters, and 0 is a real number. They behave differently: you can measure len("") but not len(None). Code that treats them as identical, usually through loose truthiness checks, tends to produce confusing errors.
How do I find which line set my variable to None?
Print the variable at several checkpoints, or use your editor’s debugger with a breakpoint just before the crash and inspect the call stack. For function-related causes, also print inside the function right before it ends, to see whether the return path you expected is the one that actually ran.
Can a library function return None unexpectedly?
Yes, especially lookups and parsers. Reading documentation for the exact call matters: many functions return None to signal “not found” rather than raising an exception. Build the habit of checking a fresh API result before chaining methods onto it.
Is it okay to just wrap the line in try/except AttributeError?
As a temporary diagnostic, maybe; as a fix, no. Swallowing the error leaves your program running with a missing value, which usually reappears as wrong output or a different crash later. Find where the None originated and fix it there.


Leave a Reply