Understanding None as a Singleton in Python

In Python, None is the standard constant used to signal the absence of a value or an empty state, implemented strictly as a singleton instance of the NoneType class. This article examines how Python internally defines None within the CPython runtime, why only a single instance exists across the interpreter's lifecycle, the technical distinction between identity and equality checks, and how the interpreter enforces its immutability.

The Singleton Nature of None

A singleton is a design pattern that restricts the instantiation of a class to a single object. In Python, None is an absolute singleton: there is only one None object created when the Python interpreter starts, and it persists until the process terminates.

Regardless of where, when, or how many times you assign None to a variable, every variable points to the exact same location in memory.

a = None
b = None

print(a is b)        # True
print(id(a) == id(b)) # True

Because None is a singleton, checking for it requires checking object identity rather than value equality.

Implementation in CPython

Under the hood in CPython (the reference implementation of Python written in C), None is defined as a static object.

  1. The C Struct: In the CPython source code (object.h and object.c), None is defined as a PyObject structure named _Py_NoneStruct.
  2. The Macro: The C API provides a global macro, Py_None, which points directly to the address of _Py_NoneStruct:
    #define Py_None (&_Py_NoneStruct)
  3. Reference Handling: Whenever a Python function does not explicitly return a value, the interpreter returns Py_None. In earlier versions of Python, every reference to None incremented its reference count via Py_INCREF(Py_None). Starting in Python 3.12, None was converted into an "immortal object," meaning its reference count remains effectively constant, avoiding memory bus contention across multi-threaded applications.

Preventing Re-instantiation

Python enforces the singleton pattern by preventing user-level creation of NoneType instances. The class of None is NoneType, accessible via type(None).

If you attempt to call NoneType() directly to create a new instance, Python raises a TypeError:

NoneType = type(None)
new_instance = NoneType()
# TypeError: cannot create 'NoneType' instances

Furthermore, None is a reserved keyword in Python. You cannot reassign it, shadow it in local scopes, or bind a new value to the identifier:

None = 5
# SyntaxError: cannot assign to None

Identity (is) vs. Equality (==)

Because None is guaranteed to be a singleton, the recommended and idiomatic way to test whether a value is None is the is operator, not ==.

class FaultyComparison:
    def __eq__(self, other):
        return True

obj = FaultyComparison()

print(obj == None) # True (Misleading)
print(obj is None) # False (Accurate)

Using is guarantees that the comparison checks for the actual, unique singleton object defined by the interpreter.