Python NoneType Explained
Data Types Satellite
NoneType: The Absence of Value
`None` signals "no value" in Python. Treat it intentionally so APIs communicate when data is optional.
What is None?
- The single instance of type
NoneType—there is only ever oneNoneobject. - Falsy in a boolean context.
- The implicit return value of any function that doesn't
returnanything.
type(None) # <class 'NoneType'>
def log(msg):
print(msg) # no return statement
log("hi") is None # True — it returned None
Checking for None
Because None is a singleton, test identity with is, never ==:
if result is None:
raise ValueError("No data")
if result is not None:
process(result)
Custom classes can override == to return surprising results, so value == None is unreliable. value is None compares object identity and is always correct—and faster.
None vs empty vs zero
A frequent bug is treating None, 0, and "" as interchangeable. They are all falsy but mean different things:
count = 0 # a real value: zero items
count = None # no value yet / not provided
if count is None: # "was it supplied?"
if not count: # True for 0, "", [], AND None — usually too broad
Use is None when you specifically mean "absent," and reserve truthiness checks for "empty or absent, don't care which."
The mutable default argument trap
Never use a mutable default like [] or {}. Use None as a sentinel and build the real default inside:
def add_item(item, bucket=None):
if bucket is None:
bucket = [] # fresh list on every call
bucket.append(item)
return bucket
A default of bucket=[] is created once and shared across all calls, so it accumulates state between calls—a classic source of bugs.
Common use cases
- Optional parameters and return values.
- Sentinel defaults (
def save(data=None): ...). - Placeholders for values that are computed later.
Next up in your learning path
Frequently Asked Questions
Should I use is None or == None?
Always use is None. None is a singleton, so identity comparison is correct and fast. == None can give wrong answers because a class may override __eq__ to return unexpected results.
if result is None: # correct
...
if result is not None: # correct
What is the difference between None and 0 or an empty string?
None means "no value at all," while 0 and "" are real values that happen to be falsy. Use is None to detect absence specifically; use a truthiness test only when empty and absent should be treated the same.
count = 0
count is None # False — zero is a real value
if not count: # True for 0, "", [] AND None — often too broad
...
Why should I not use a mutable default argument?
A default like def f(x=[]) is created once when the function is defined, and every call shares it, so it retains data between calls. Use x=None and create the list inside the function to get a fresh one each time.
def add(item, bucket=None):
if bucket is None:
bucket = [] # fresh list every call
bucket.append(item)
return bucket
What does a function return if it has no return statement?
It returns None. The same applies to a bare return with no value. This is why methods that mutate in place, like list.sort(), return None rather than the modified object.
nums = [3, 1, 2]
result = nums.sort() # sorts in place...
result # None — a classic gotcha