operator.is_none en Python ofrece una función reutilizable para comprobar si un valor es exactamente None. En lugar de escribir una lambda cada vez que una API espera un predicado, puedes pasar operator.is_none directamente. Su función complementaria, operator.is_not_none, devuelve verdadero cuando el valor no es None.
El recurso es pequeño, pero mejora la claridad en filtros, validaciones, procesamiento de colecciones, registros de callbacks y pipelines funcionales. No sustituye la expresión habitual valor is None dentro de un condicional simple. Su ventaja aparece cuando la comprobación debe tratarse como una función.
Por qué comparar None por identidad
None es un singleton que representa ausencia de información, resultado inexistente o estado aún no inicializado. La comparación recomendada es:
valor = None
if valor is None:
print("sin valor")
Evita valor == None, porque una clase puede personalizar __eq__ y producir resultados inesperados. El operador is comprueba identidad de objeto.
Comportamiento básico
from operator import is_none, is_not_none
print(is_none(None)) # True
print(is_none(0)) # False
print(is_not_none("")) # True
print(is_not_none(False)) # True
Los valores falsy no son necesariamente ausentes. Cero, cadena vacía, lista vacía y False pueden ser datos válidos. Esta diferencia es esencial en formularios, configuraciones, APIs y actualizaciones parciales.
Filtrar valores ausentes
from operator import is_not_none
valores = [10, None, 0, "", None, 25]
limpios = list(filter(is_not_none, valores))
print(limpios) # [10, 0, '', 25]
filter(None, valores) también eliminaría cero y la cadena vacía. El predicado con nombre expresa la regla exacta: quitar solamente None.
Separar datos presentes y ausentes
from operator import is_none, is_not_none
respuestas = ["sí", None, "no", "", None]
ausentes = list(filter(is_none, respuestas))
presentes = list(filter(is_not_none, respuestas))
Este patrón es útil en informes de calidad, validación de campos opcionales, procesos ETL y limpieza de formularios.
Uso con map, any y all
from operator import is_none
campos = ["Ana", "ana@example.com", None]
hay_ausentes = any(map(is_none, campos))
todos_ausentes = all(map(is_none, campos))
Una expresión generadora como any(valor is None for valor in campos) también es excelente y puede ser más legible. La función de operator destaca cuando necesitas almacenar, registrar o componer el predicado.
Combinar con itertools
from itertools import filterfalse
from operator import is_none
valores = [1, None, 2, None, 3]
presentes = list(filterfalse(is_none, valores))
En este caso, filter(is_not_none, valores) es más corto, pero el ejemplo muestra cómo un predicado con nombre se integra en distintas APIs funcionales.
Comparación con lambda
limpios = list(filter(lambda elemento: elemento is not None, valores))
La lambda sigue siendo válida y compatible con versiones antiguas. La función de operator evita repetir la misma expresión y proporciona un nombre claro en documentación, trazas y tablas de callbacks. Una lambda sigue siendo apropiada cuando la regla combina ausencia con validaciones adicionales.
Limpiar diccionarios
from operator import is_not_none
payload = {
"nombre": "Ana",
"edad": None,
"activo": False,
"apodo": "",
}
limpio = {
clave: valor
for clave, valor in payload.items()
if is_not_none(valor)
}
El resultado conserva False y la cadena vacía, eliminando solamente la edad ausente. Es útil al construir peticiones HTTP, documentos y actualizaciones de bases de datos.
Argumentos opcionales
from operator import is_none
def crear_cambios(nombre=None, activo=None):
cambios = {}
if not is_none(nombre):
cambios["nombre"] = nombre
if not is_none(activo):
cambios["activo"] = activo
return cambios
Una llamada con nombre="" entrega explícitamente una cadena vacía, mientras que omitir el argumento significa no modificarlo. En APIs más complejas, una sentinela personalizada permite distinguir “no enviado” de “enviado como None”.
Registro de predicados
from operator import is_none, is_not_none
REGLAS = {
"requerido_ausente": is_none,
"opcional_presente": is_not_none,
}
resultado = REGLAS["opcional_presente"]("dato")
Este enfoque puede simplificar validadores de esquemas, motores de workflows, herramientas CLI y pasos configurables de procesamiento.
Compatibilidad
Antes de usar las funciones en una biblioteca, confirma la versión mínima de Python. Para runtimes anteriores, el fallback es sencillo:
try:
from operator import is_none, is_not_none
except ImportError:
def is_none(value):
return value is None
def is_not_none(value):
return value is not None
En aplicaciones controladas, declarar la versión requerida en pyproject.toml suele ser más limpio que mantener múltiples ramas.
Rendimiento y legibilidad
No elijas el recurso únicamente por microoptimización. Las comparaciones de identidad ya son baratas y la legibilidad importa más. Usa valor is None en condicionales directos. Usa el callable de operator cuando una función deba pasarse como argumento o compartirse entre etapas.
Pruebas recomendadas
from operator import is_none, is_not_none
assert is_none(None)
assert not is_none(False)
assert not is_none(0)
assert not is_none("")
assert is_not_none([])
assert is_not_none({})
Los casos falsy son esenciales para evitar que una refactorización cambie una regla de identidad por una regla de verdad.
Errores comunes
No uses la función para decidir si una colección está vacía; utiliza longitud o truthiness. No consideres todo None inválido sin entender el dominio. No ocultes un condicional sencillo detrás de una abstracción funcional si reduce la claridad. Documenta siempre si None significa ausente, desconocido, deshabilitado o intencionalmente vacío.
Buenas prácticas
Mantén explícita la semántica de ausencia, conserva valores falsy válidos y usa sentinelas personalizadas cuando una interfaz necesite más de dos estados. Prefiere predicados con nombre en tablas de callbacks y pipelines reutilizables, pero conserva expresiones directas en el flujo local.
Para ampliar el tema, consulta nuestras guías sobre operator en Python, itertools en Python, map, filter y reduce y type hints en Python.
Como referencias externas, revisa la documentación oficial de operator y la PEP 8, que recomienda comparar singletons por identidad.
Conclusión
operator.is_none y operator.is_not_none convierten comprobaciones precisas de identidad en callables reutilizables. Su valor principal es expresar intención: permiten distinguir None de valores falsy válidos sin repetir lambdas. Úsalas cuando una API requiera un predicado y conserva is None para condicionales ordinarios.







