None is Python's value for "nothing here": no answer yet, no result, or an option that wasn't given. It is the only value of the type NoneType, and it plays the role that null plays in Java, JavaScript and SQL.
estimate = None # the repair hasn't been inspected yet
if estimate is None:
print("Awaiting inspection")This lesson explains how None differs from zero and empty values, why you test for it with is rather than ==, why functions return it when they have no return statement, and how it solves the mutable default argument problem. The examples come from a repair desk that must tell an unknown estimate apart from a free repair.
Absent values
None means the value is absent, which is different from every other "empty-looking" value:
| Value | Meaning at the repair desk |
|---|---|
None | Estimate not known yet |
0 | Repair is free |
False | A yes/no answer that is "no" |
"" | A note that exists but is blank |
Keeping these apart lets a program give the right message. If an unknown estimate were stored as 0, the customer would be told the repair is free.
Use None as the starting value of a variable that will be filled in later, as the result of a search that found nothing (dict.get() returns None for a missing key), and for optional fields in records. Avoid using it to mean an error occurred; raise an exception instead, so the problem can't be ignored.
Identity tests
There is exactly one None object in a Python program, so the correct test is identity: value is None, or value is not None.
estimate = 0
print(estimate is None) # False: 0 is a real estimate
print(not estimate) # True: 0 is falsy, so this test is wrong herenot estimate and if estimate: treat None, 0, "" and empty lists the same way, which is exactly the confusion to avoid when 0 is meaningful. PEP 8 recommends is None over == None, because a class can redefine == to return something unexpected, while is can't be overridden.
Doing arithmetic or calling methods on None raises errors such as TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' or AttributeError: 'NoneType' object has no attribute 'upper'. When you see NoneType in a traceback, find where the variable was expected to get a real value and didn't.
Implicit results
Every function returns something. If execution reaches the end of the body without a return, or hits a bare return, the result is None:
def reminder(name):
print(f"Collect your bike, {name}")
result = reminder("Ana") # prints the message
print(result) # NonePrinting is not returning. reminder() shows text on the screen, but the caller receives nothing it can store or reuse. Many built-in methods that change an object in place also return None on purpose, to signal that they didn't create a new object: list.sort(), list.append() and dict.update() all return None. Writing notes = notes.append("done") therefore replaces the list with None.
Optional defaults
None is the standard default for an optional argument, especially when the real default is a mutable object such as a list:
def add_note(text, notes=None):
if notes is None:
notes = [] # a fresh list on every call
notes.append(text)
return notes
print(add_note("brakes")) # ['brakes']
print(add_note("chain")) # ['chain']Writing notes=[] instead would create one list when the function is defined and share it between every call, so the second call would return ['brakes', 'chain']. Using None also lets a function tell "argument not given" apart from any real value, including 0 and empty strings. In type hints, an optional value is written str | None (or Optional[str] before Python 3.10).
Independent practice and a worked check
Task: display separate messages for unknown, free and priced repairs. Write a function that takes an estimate and returns one of three messages, then test it with None, 0 and 30.
def repair_message(estimate):
if estimate is None:
return "We'll call you with a quote."
if estimate == 0:
return "Good news: no charge."
return f"Your repair will cost £{estimate}."
for value in (None, 0, 30):
print(repair_message(value))The order of the checks matters: testing if not estimate: first would give None and 0 the same message. For the worked check, the test that specifically checks for None is value is None.
Reference and next practice
The documentation describes the None constant and truth value testing. Continue with function arguments for more on defaults, and booleans for truthiness. Practise with the Python exercises and Python quiz.
The None Value Summary
- Absent values: None represents the absence of a meaningful value.
- Identity tests: is None singles out the absence marker.
- Implicit results: Functions with no explicit returned value produce None.
- Optional defaults: None can mark an omitted argument so a fresh collection is created inside the function.
The None Value Examples
Each example shows the code, the output it produces and what each part does.
The None Value in a small program
estimate = None
if estimate is None:
print("Awaiting inspection")
free_repair = 0
print(free_repair is None)Awaiting inspection
FalseLine-by-line explanation
- Lines 1 to 3
estimateisNone, so the identity test is true and the message prints. - Lines 4 to 5A free repair is stored as 0. Zero is a real value, so
free_repair is NoneisFalse.
Three kinds of estimate
def describe(estimate):
if estimate is None:
return "Awaiting inspection"
if estimate == 0:
return "Free repair"
return f"Estimated cost: £{estimate:.2f}"
jobs = {"Ana": None, "Ben": 0, "Cara": 45.5}
for name, estimate in jobs.items():
print(f"{name}: {describe(estimate)}")
print(jobs.get("Dev"))
print(jobs.get("Dev", "no booking"))Ana: Awaiting inspection
Ben: Free repair
Cara: Estimated cost: £45.50
None
no bookingLine-by-line explanation
- Lines 2 to 5
Noneis checked first and separately from 0, so each case gets its own message. - Line 12
get()returnsNonewhen the key is missing. - Line 13A second argument replaces that
Nonewith a default of your choice.
Common The None Value Mistakes
Using a falsy test when 0 is a valid value
estimate = 0
if not estimate:
print("Awaiting inspection") # wrong: the repair is freeestimate = 0
if estimate is None:
print("Awaiting inspection")not estimate is true for both None and 0. Test for None explicitly when zero means something.
Assigning the result of an in-place method
notes = ["brakes"]
notes = notes.append("chain")
print(notes) # Nonenotes = ["brakes"]
notes.append("chain")
print(notes) # ['brakes', 'chain']The None Value in Real Projects
None in databases and APIs
None is how Python represents missing data from outside sources. Database drivers turn SQL NULL into None, and json.loads() turns JSON null into None. Getting the distinction right in Python keeps it right in the database: an unknown price stays unknown rather than becoming 0 and skewing averages.
Type checkers such as mypy make None handling safer. If a function is annotated -> float | None, mypy warns when a caller does arithmetic on the result without first checking is not None, catching the classic NoneType error before the code runs.
The None Value FAQ
Is None the same as null in Python?
Python has no null keyword; None serves the same purpose. When Python reads JSON, null becomes None, and database drivers convert SQL NULL to None as well.
Why use is None instead of == None?
None is a single object, so identity is the precise test. is can't be overridden by a class, while == can, so x == None might give a misleading result for some objects. PEP 8 recommends is None and is not None.
Is None equal to False or 0?
No. None == False and None == 0 are both False. None is falsy, so it behaves like False in an if condition, but it is a distinct value with its own type, NoneType.
Why does my function return None?
Either it has no return statement, a return without a value ran, or the code path that returns a value wasn't reached, for example an if without an else. Also check that you didn't print() the answer instead of returning it.
How do I replace None with a default value?
Use a conditional expression: value = default if value is None else value. The shorter value or default also works, but it replaces 0, empty strings and other falsy values too, so only use it when those can't be valid.
The None Value Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which test specifically checks for None?
Which review concern is valid for the none value?
The None Value Quiz
2 questions to check what you learned.
Which test specifically checks for None?
- not value
- value is None
- Python ignores the distinction
Which statement correctly describes implicit results?
- Functions with no explicit returned value produce None.
- Only the example output matters, not the rule
- Every operation has the same behavior