Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Explainer

Python Nil Means None: Missing Is Not the Same as Empty

Sean

Platform Writer

Aug 01, 2026
8 min read

Python uses None, not nil or null, to represent the absence of a value, and the reliable check is value is None.

Python Nil Means None: Missing Is Not the Same as Empty

The syntax is simple. The design decision is not. Production bugs appear when missing, empty, zero, false, invalid, and not-yet-loaded are squeezed into one vague falsy bucket.

Table of contents

None is a singleton with its own type

None is the single instance of NoneType. Functions without an explicit return value return it automatically. It can also be an intentional placeholder, a default argument, or a signal that a lookup found no value.

result = None

if result is None:
    print('No result yet')

print(type(result))  # NoneType

Use is None and is not None. Identity expresses the singleton check directly and cannot be surprised by a class that overloads equality. Style guides recommend it because the code says exactly what it means.

Missing, empty, zero, and false are different states

None, '', 0, False, and empty containers are all falsy, but they often carry different business meaning. A zero balance exists. An empty list may be a completed query with no matches. None may mean the query never ran or the field was omitted.

def describe_limit(limit):
    if limit is None:
        return 'use the account default'
    if limit == 0:
        return 'disable processing'
    return f'process up to {limit}'

Write a truthiness check only when all falsy values genuinely share behavior. Otherwise compare the state you intend. Short code is not automatically clear code.

Use explicit sentinels when None is valid data

Sometimes None is a legitimate value and you still need to distinguish it from an omitted argument. Create a unique sentinel object. Frameworks use this pattern for configuration, patch requests, caches, and lazy loading.

MISSING = object()

def update_email(value=MISSING):
    if value is MISSING:
        return 'leave unchanged'
    if value is None:
        return 'clear email'
    return f'set email to {value}'

A named sentinel turns an implicit convention into a state the code can test. For public APIs, document it through types and request schemas rather than leaking a private object across boundaries.

Handle None at database and API boundaries

SQL NULL, JSON null, and Python None often map to one another, but their surrounding semantics differ. PATCH requests may distinguish an omitted field from an explicit null. Database constraints may allow null but reject empty strings. Serialization libraries may omit None fields or emit them depending on configuration.

Validate at the boundary and keep the internal model intentional. Optional type hints such as str | None communicate that absence is allowed, but they do not validate runtime input or explain what absence means to the product.

Make absence observable without making it noisy

Do not catch every AttributeError and blame None. Validate critical inputs near entry points, fail with context, and log identifiers rather than secrets. A stack trace that says an object has no attribute is less useful than an error explaining which upstream field was missing.

Defaults should be deliberate too. Replacing every None with a convenient value can hide upstream data loss. Decide where a default is safe, where absence should propagate, and where the request must fail.

How this fits the rest of the stack

If the application behind that data model needs an API, database, storage, and background work, put the line items beside each other in the RunxBuild hosting calculator. The RunxBuild dashboard is there when the model is ready to become a deployed service.

Useful related references:

FAQ

What is nil in Python?

Python does not have a nil keyword. The equivalent concept is represented by the singleton value None.

Should I use == None or is None?

Use is None. It checks identity with the singleton and avoids custom equality behavior.

Is None the same as an empty string?

No. Both are falsy, but an empty string is a present string with zero characters while None represents absence.

What type is None?

Its type is NoneType. Modern type hints commonly express an optional string as str | None.

Is None the same as NaN?

No. None represents absence as a Python object. NaN is a special floating-point value representing an undefined or unrepresentable numeric result.

#Python nil#Python None#Null values#Python types#API design