SimpleNamespace: objetos ligeros con atributos

Publicado el: 29/08/2026
Tempo de leitura: 5 minutos
A developer typing code on a laptop with a Python book beside in an office.

A veces necesitas un objeto sencillo para agrupar valores mediante atributos sin definir una clase completa. types.SimpleNamespace ofrece exactamente eso: un contenedor mutable basado en __dict__, construido con argumentos nombrados, con representación legible e igualdad basada en los atributos almacenados.

Esta guía explica cómo crear namespaces, convertir diccionarios, añadir y eliminar atributos, comparar instancias, copiar objetos, manejar datos anidados, integrar JSON y argparse y decidir cuándo conviene una dataclass, TypedDict, NamedTuple o clase normal.

Primer SimpleNamespace

from types import SimpleNamespace

usuario = SimpleNamespace(nombre="Ana", activo=True)
print(usuario.nombre)
print(usuario.activo)

Los argumentos nombrados se insertan en el __dict__ de la instancia. No existe declaración previa de campos, validación de runtime ni conversión automática.

Añadir atributos después

usuario.id = 42
usuario.email = "ana@example.com"

El objeto es dinámico y mutable. Esto resulta práctico para prototipos y estado temporal, pero un nombre escrito incorrectamente puede crear un nuevo atributo en silencio.

Construir desde un diccionario

datos = {"host": "localhost", "puerto": 8000}
config = SimpleNamespace(**datos)
print(config.puerto)

Las claves deben ser strings aceptadas como nombres de argumentos. Claves con guiones, espacios o valores no textuales no pueden expandirse directamente con **.

Volver a diccionario

mapping = vars(config)

vars(config) devuelve el diccionario real de atributos, no una copia. Modificarlo cambia el namespace.

snapshot = vars(config).copy()

Crea una copia cuando necesites estado independiente.

Representación legible

print(SimpleNamespace(x=1, y=2))
# namespace(x=1, y=2)

La representación ayuda en pruebas y depuración, pero puede mostrar datos sensibles. Elimina contraseñas, tokens y datos personales antes de registrar el objeto.

Igualdad

a = SimpleNamespace(x=1, y=2)
b = SimpleNamespace(y=2, x=1)
print(a == b)  # True

La igualdad compara los diccionarios de atributos. El orden de inserción no importa. Como la clase es mutable, no está pensada como clave hashable ni miembro de set.

Eliminar atributos

del usuario.email

Acceder al atributo eliminado genera AttributeError. Usa hasattr() o getattr(objeto, nombre, predeterminado) para campos opcionales.

getattr y setattr dinámicos

nombre_campo = "timeout"
setattr(config, nombre_campo, 30)
valor = getattr(config, nombre_campo)

Estas funciones son útiles cuando los nombres proceden de metadatos. Valida una allowlist antes de aceptar nombres externos, especialmente si podrían sobrescribir atributos especiales.

Namespaces anidados

app = SimpleNamespace(
    base_datos=SimpleNamespace(host="db", puerto=5432),
    debug=False,
)

Los diccionarios internos no se convierten automáticamente. Construye la estructura explícitamente cuando quieras notación por punto.

Conversión recursiva

def a_namespace(valor):
    if isinstance(valor, dict):
        return SimpleNamespace(
            **{clave: a_namespace(item) for clave, item in valor.items()}
        )
    if isinstance(valor, list):
        return [a_namespace(item) for item in valor]
    return valor

Antes de usar este helper con datos externos, verifica que todas las claves sean identificadores adecuados y que no se acepten nombres especiales inesperados.

Serialización JSON

El encoder JSON estándar no serializa SimpleNamespace directamente:

import json

texto = json.dumps(config, default=vars)

default=vars también puede exponer atributos de otros objetos con __dict__. La conversión explícita es más segura en APIs públicas.

Copias

from copy import copy

copia = copy(app)

Una copia superficial crea otro namespace, pero los valores mutables internos continúan compartidos. Usa deepcopy() solo cuando la estructura lo soporte y el coste esté justificado.

Integración con argparse

ArgumentParser.parse_args() devuelve un objeto similar y puede rellenar una instancia existente:

from argparse import ArgumentParser
from types import SimpleNamespace

parser = ArgumentParser()
parser.add_argument("--puerto", type=int, default=8000)
config = parser.parse_args(namespace=SimpleNamespace())

En aplicaciones grandes, valida y convierte el resultado a un modelo explícito antes de iniciar servicios.

Prototipos y fixtures

SimpleNamespace es útil para pruebas rápidas, stubs, fixtures y valores de retorno internos cuando una clase formal añade demasiado código. resultado.valor puede ser más legible que índices de tupla.

No es un schema

El objeto no declara campos obligatorios, tipos, defaults ni documentación. Los analizadores estáticos tienen poca información sobre atributos dinámicos. Una dataclass o TypedDict ofrece un contrato más fuerte.

SimpleNamespace frente a dataclass

from dataclasses import dataclass

@dataclass
class Config:
    host: str
    puerto: int = 8000

Dataclass ofrece campos explícitos, type hints, construcción predecible, opciones de inmutabilidad y mejor soporte de IDE. Usa SimpleNamespace cuando la forma sea temporal o realmente dinámica.

Frente a TypedDict

TypedDict describe diccionarios accedidos por claves y sirve principalmente al análisis estático. SimpleNamespace proporciona acceso por atributos en runtime. Elige según el formato real de los datos.

Frente a NamedTuple

NamedTuple es inmutable, indexable, hashable y posee campos fijos. SimpleNamespace es mutable, no está orientado a índices y acepta atributos nuevos. Para registros estables y ligeros, NamedTuple puede ser mejor.

Frente a una clase normal

Una clase permite invariantes, propiedades, métodos, validación y encapsulación. Cuando el objeto gana comportamiento o forma parte de una API pública, migra a una clase explícita.

Proporcionar defaults

def nueva_config(**overrides):
    valores = {"host": "localhost", "puerto": 8000, "debug": False}
    desconocidas = set(overrides) - set(valores)
    if desconocidas:
        raise TypeError(f"opciones desconocidas: {sorted(desconocidas)}")
    valores.update(overrides)
    return SimpleNamespace(**valores)

Comprobar nombres desconocidos evita errores tipográficos silenciosos.

Campos calculados

Puedes guardar un valor calculado, pero no se actualizará cuando cambien sus dependencias. Usa una propiedad en una clase si el valor debe derivarse siempre del estado actual.

Herencia

SimpleNamespace puede heredarse, pero si necesitas métodos, validación y estructura fija, una clase normal o dataclass suele comunicar mejor la intención.

Seguridad con datos externos

No conviertas JSON arbitrario a atributos para después controlar imports, rutas, queries o llamadas sin validación. La notación por punto no vuelve confiable la entrada.

Concurrencia

El namespace no sincroniza accesos. Varias threads modificando atributos requieren la misma disciplina de locks que un diccionario compartido. Para configuración leída por muchos workers, prefiere snapshots inmutables.

Errores comunes

  • Tratarlo como modelo validado: cualquier atributo puede crearse.
  • Usar vars como mapping independiente: devuelve el diccionario vivo.
  • Esperar conversión recursiva: los dict internos siguen siendo dict.
  • Publicarlo como contrato estable: los campos no están declarados.
  • Registrar secretos: el repr muestra atributos.
  • Suponer que una copia superficial aísla: los objetos internos siguen compartidos.

Ejemplo completo: resultado de procesamiento

from types import SimpleNamespace

def procesar(lineas):
    errores = []
    validas = []
    for numero, linea in enumerate(lineas, 1):
        try:
            validas.append(normalizar(linea))
        except ValueError as error:
            errores.append((numero, str(error)))

    return SimpleNamespace(
        total=len(lineas),
        validas=validas,
        errores=errores,
        exito=not errores,
    )

resultado = procesar(lineas)
if resultado.exito:
    guardar(resultado.validas)

El namespace funciona como retorno interno sencillo. Si el resultado se convierte en parte de una biblioteca pública, una dataclass tipada ofrece un contrato más claro.

Conclusión

types.SimpleNamespace es un contenedor ligero para valores accedidos mediante atributos. Reduce boilerplate en prototipos, pruebas y estructuras temporales, con representación e igualdad útiles.

La documentación oficial de SimpleNamespace define la clase. Úsala para datos dinámicos simples y migra a dataclass, TypedDict, NamedTuple o clase normal cuando necesites schema, validación o comportamiento.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Carpetas y directorios para contextlib.chdir en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaura directorios automáticamente

    Aprende contextlib.chdir en Python para cambiar directorios temporalmente, restaurar rutas y crear pruebas confiables sin errores de estado global.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Monitoreo de rendimiento y ejecución de código Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sys.monitoring: instrumentación de bajo overhead

    Aprende sys.monitoring en Python para instrumentar ejecución con bajo overhead, eventos selectivos, callbacks y observabilidad segura.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Desarrollador organizando datos con operator.attrgetter en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    operator.attrgetter: ordena objetos por atributos

    Aprende operator.attrgetter en Python para ordenar, agrupar y transformar objetos por atributos simples o anidados con código claro.

    Ler mais

    Tempo de leitura: 4 minutos
    02/09/2026
    Programación asíncrona con asyncio.Runner en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Runner: reutiliza el event loop con seguridad

    Aprende asyncio.Runner en Python para reutilizar el event loop, controlar contexto, señales, debug, cancelación y cierre asíncrono seguro.

    Ler mais

    Tempo de leitura: 7 minutos
    02/09/2026
    Compresión de datos binarios con Zstandard en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard con streams y diccionarios

    Aprende compression.zstd en Python para comprimir datos con Zstandard, streaming, diccionarios y límites seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    01/09/2026
    Aplicación Python empaquetada como archivo ejecutable con zipapp
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    zipapp en Python: crea apps ejecutables

    Aprende zipapp en Python para empaquetar aplicaciones como archivos pyz ejecutables, incluir dependencias y distribuirlas con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    01/09/2026