tempfile en Python: archivos temporales

Publicado el: 29/07/2026
Tempo de leitura: 8 minutos
Archivos organizados que representan almacenamiento temporal seguro en Python

Los archivos temporales aparecen en exportaciones, cargas, pruebas, conversiones, descargas, procesamiento de imágenes y comunicación con programas externos. Crearlos manualmente en una carpeta fija parece sencillo, pero puede causar colisiones de nombres, permisos débiles, datos abandonados y vulnerabilidades de carrera. El módulo tempfile en Python ofrece APIs seguras y portables para archivos y directorios temporales con limpieza automática.

Esta guía explica TemporaryFile, NamedTemporaryFile, SpooledTemporaryFile, TemporaryDirectory, mkstemp() y mkdtemp(), además de diferencias entre Windows y Unix, modos binario y texto, nombres visibles, limpieza, pruebas y seguridad. Complementa nuestros artículos sobre listas en Python, slicing, la sentencia with, FileNotFoundError y archivos ZIP seguros.

Por qué no crear nombres temporales manualmente

Un código como open('/tmp/salida.txt', 'w') puede funcionar en una prueba aislada, pero es frágil en producción. Dos procesos pueden elegir el mismo nombre, otro proceso puede crear un archivo o enlace antes que tu programa y una ruta fija puede no existir o no tener permisos en otra plataforma.

tempfile combina la elección segura del nombre y la creación en una sola operación. Los nombres incorporan caracteres aleatorios y los permisos siguen reglas apropiadas para el usuario que crea el recurso.

TemporaryFile para almacenamiento simple

TemporaryFile() devuelve un objeto similar a un archivo. El modo predeterminado es binario de lectura y escritura, w+b, y el recurso se elimina al cerrarse.

from tempfile import TemporaryFile

with TemporaryFile() as archivo:
    archivo.write(b"resultado temporal")
    archivo.seek(0)
    datos = archivo.read()
    print(datos)

El bloque with garantiza cierre y limpieza incluso si ocurre una excepción. En Unix, el archivo puede no tener una entrada visible en el directorio. Otras plataformas pueden usar internamente un archivo con nombre. No hagas depender la lógica de si existe un camino visible.

Modo texto y codificación

Para contenido textual, declara el modo y la codificación explícitamente.

from tempfile import TemporaryFile

with TemporaryFile(mode="w+t", encoding="utf-8") as archivo:
    archivo.write("Hola, archivo temporal!\n")
    archivo.seek(0)
    print(archivo.read())

Los parámetros explícitos evitan diferencias de codificación entre máquinas. Conserva el modo binario para imágenes, PDFs, ZIPs y datos de red.

NamedTemporaryFile cuando necesitas una ruta

Algunas bibliotecas y herramientas de línea de comandos aceptan solo un nombre de archivo. NamedTemporaryFile() crea una ruta visible y la expone mediante name.

from tempfile import NamedTemporaryFile

with NamedTemporaryFile(suffix=".json") as archivo:
    print(archivo.name)
    archivo.write(b'{"estado": "ok"}')
    archivo.flush()
    # pasa archivo.name a otra API

El sufijo resulta útil cuando una herramienta detecta el formato por la extensión. También puedes definir prefix y dir; usa argumentos con nombre para mejorar la legibilidad.

delete y delete_on_close

De forma predeterminada, un archivo temporal con nombre se elimina al cerrarse. Desde Python 3.12, delete_on_close permite separar el cierre del objeto de la eliminación al salir del contexto.

from tempfile import NamedTemporaryFile

with NamedTemporaryFile(
    mode="w+b",
    suffix=".bin",
    delete=True,
    delete_on_close=False,
) as archivo:
    ruta = archivo.name
    archivo.write(b"datos")
    archivo.close()

    with open(ruta, "rb") as lectura:
        print(lectura.read())
# eliminado al salir del contexto exterior

Este patrón ayuda cuando otra biblioteca debe reabrir el archivo por nombre. Si usas delete=False, la aplicación asume toda la responsabilidad de limpieza.

Diferencias importantes en Windows

Los sistemas POSIX suelen permitir reabrir o eliminar un archivo mientras sigue abierto. Windows aplica reglas más estrictas de compartición y acceso de borrado. Reabrir un NamedTemporaryFile aún abierto puede fallar según delete, delete_on_close y cómo se cree el segundo descriptor.

Una estrategia predecible consiste en usar delete_on_close=False, cerrar el objeto original antes de reabrir por nombre y cerrar todos los demás descriptores antes de salir del contexto. Prueba el flujo en el mismo sistema operativo de producción.

TemporaryDirectory para un espacio completo

Cuando un trabajo usa varios archivos, crea un directorio temporal aislado.

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory(prefix="informe-") as carpeta:
    raiz = Path(carpeta)
    entrada = raiz / "entrada.csv"
    salida = raiz / "salida.json"

    entrada.write_text("nombre,valor\nA,10\n", encoding="utf-8")
    salida.write_text('{"total": 10}', encoding="utf-8")

    print(list(raiz.iterdir()))
# carpeta y contenido eliminados

El valor del contexto contiene la ruta y la limpieza es recursiva. Es ideal para pruebas de importación, extracción controlada, conversión multimedia y procesos de compilación.

delete e ignore_cleanup_errors

TemporaryDirectory acepta ignore_cleanup_errors para una limpieza de mejor esfuerzo, útil cuando Windows conserva un archivo abierto. Desde Python 3.12, delete=False puede preservar el árbol después de salir del contexto para depuración.

from tempfile import TemporaryDirectory

with TemporaryDirectory(delete=False) as carpeta:
    print("Conservada para inspección:", carpeta)

No mantengas esta opción en producción sin una política de retención. Los directorios abandonados pueden llenar el disco.

SpooledTemporaryFile: memoria antes del disco

SpooledTemporaryFile mantiene datos en memoria hasta superar max_size o hasta que una operación como fileno() exija un archivo real. Después realiza el rollover al disco.

from tempfile import SpooledTemporaryFile

with SpooledTemporaryFile(max_size=1024 * 1024) as archivo:
    archivo.write(b"contenido pequeño")
    archivo.seek(0)
    print(archivo.read())

Esta clase funciona bien para uploads, respuestas generadas y transformaciones que normalmente son pequeñas, pero pueden crecer. Combina velocidad en memoria con una salida segura al disco.

Forzar rollover

Llama a rollover() cuando otra API requiera un descriptor real.

with SpooledTemporaryFile(max_size=10_000) as archivo:
    archivo.write(b"abc")
    archivo.rollover()
    print(archivo.fileno())

No dependas del atributo interno _file. Usa la interfaz pública de archivo.

mkstemp(): API de bajo nivel

mkstemp() crea un archivo de forma segura y devuelve un descriptor del sistema operativo junto con una ruta absoluta.

import os
from tempfile import mkstemp

fd, ruta = mkstemp(suffix=".txt", prefix="proceso-")
try:
    with os.fdopen(fd, "w", encoding="utf-8") as archivo:
        archivo.write("contenido")
finally:
    if os.path.exists(ruta):
        os.unlink(ruta)

La función no elimina el archivo automáticamente. Cerrar el descriptor no borra la ruta. Prefiere context managers de alto nivel salvo que necesites control del descriptor.

mkdtemp(): limpieza manual del directorio

mkdtemp() crea un directorio seguro y devuelve una ruta absoluta. Tu código debe eliminar el árbol.

import shutil
from pathlib import Path
from tempfile import mkdtemp

carpeta = Path(mkdtemp(prefix="job-"))
try:
    (carpeta / "resultado.txt").write_text("ok", encoding="utf-8")
finally:
    shutil.rmtree(carpeta, ignore_errors=False)

Cuando la limpieza automática es válida, TemporaryDirectory es más simple y menos propenso a fugas.

Nunca uses mktemp()

La documentación oficial de tempfile marca mktemp() como obsoleto e inseguro. Genera un nombre que no existía al llamar, pero no crea el archivo inmediatamente. Otro proceso puede ocuparlo antes de la apertura.

Usa NamedTemporaryFile o mkstemp(), que eligen el nombre y crean el recurso de forma atómica.

Elegir prefix, suffix y dir

prefix ayuda a identificar recursos durante depuración, suffix conserva una extensión necesaria y dir controla la ubicación.

with NamedTemporaryFile(
    prefix="miniatura-",
    suffix=".png",
    dir="/ruta/controlada",
) as imagen:
    pass

El directorio debe existir y permitir escritura. No construyas prefijos a partir de entrada no confiable. Aunque la parte aleatoria sea segura, un texto malicioso puede confundir registros o herramientas.

Encontrar el directorio temporal predeterminado

gettempdir() devuelve el directorio seleccionado. Python considera variables como TMPDIR, TEMP y TMP, seguidas por ubicaciones específicas de la plataforma.

from tempfile import gettempdir

print(gettempdir())

No supongas que siempre será /tmp. Contenedores, servicios y sistemas empresariales pueden redirigir temporales a otro volumen. Evita cambiar globalmente tempfile.tempdir; pasa dir a la operación concreta.

flush, seek y visibilidad

Después de escribir, usa seek(0) antes de leer del mismo flujo. Si otro proceso abrirá la misma ruta, llama primero a flush() para enviar los buffers de Python al sistema operativo.

with NamedTemporaryFile() as archivo:
    archivo.write(b"123")
    archivo.flush()
    archivo.seek(0)
    assert archivo.read() == b"123"

os.fsync() solicita una persistencia más fuerte, pero rara vez tiene sentido para datos temporales y tiene un coste adicional.

Almacenamiento temporal para uploads

No mantengas uploads ilimitados completamente en memoria. Un diseño práctico transmite el flujo a SpooledTemporaryFile, impone un límite, valida el formato real, procesa y limpia al terminar.

Temporal no significa confiable. Continúa aplicando límites, antivirus cuando sea necesario, validación de contenido y protección contra bombas de descompresión o archivos malformados.

Uso con subprocesos

Si un programa acepta entrada estándar, una tubería evita crear una ruta. Cuando exige un nombre, usa NamedTemporaryFile o TemporaryDirectory, cierra y ejecuta flush según la plataforma, pasa la ruta como argumento separado y nunca construyas comandos de shell por concatenación.

Cuando la limpieza sea manual, colócala en finally. Un proceso externo fallido no debe dejar datos sensibles en el disco.

Pruebas con TemporaryDirectory

Los directorios temporales hacen que las pruebas sean independientes de la máquina.

from pathlib import Path
from tempfile import TemporaryDirectory


def guardar(ruta, texto):
    Path(ruta).write_text(texto, encoding="utf-8")

with TemporaryDirectory() as carpeta:
    destino = Path(carpeta) / "prueba.txt"
    guardar(destino, "valor")
    assert destino.read_text(encoding="utf-8") == "valor"

Cada prueba recibe un espacio aislado, reduce colisiones y no ensucia el repositorio. Los frameworks ofrecen fixtures similares, pero conocer tempfile sigue siendo útil en scripts y pruebas sin dependencias.

Seguridad y datos sensibles

El módulo crea nombres de forma segura, pero la aplicación aún debe controlar permisos, tiempo de retención y registros. No escribas rutas con identificadores sensibles en logs. Evita volúmenes compartidos sin aislamiento y considera cifrado cuando el modelo de amenazas lo exija.

En POSIX, una terminación abrupta con SIGKILL puede impedir la limpieza de archivos con nombre. Los servicios de larga duración deberían vigilar el espacio y eliminar residuos legítimos por edad y propietario.

Errores frecuentes

  • Usar nombres fijos en directorios compartidos.
  • Elegir mktemp() porque devuelve solo una ruta.
  • Olvidar seek(0) antes de leer.
  • No usar flush() antes de que otro proceso abra el archivo.
  • Suponer comportamiento POSIX en Windows.
  • Usar delete=False sin limpiar después.
  • Mantener uploads ilimitados en memoria.
  • Suponer que el directorio temporal siempre es /tmp.

Buenas prácticas

  • Prefiere context managers y APIs de alto nivel.
  • Usa TemporaryFile cuando no necesitas una ruta.
  • Usa NamedTemporaryFile cuando otra API exige un nombre.
  • Usa TemporaryDirectory para varios artefactos.
  • Usa SpooledTemporaryFile para contenido pequeño con límite.
  • Prueba la reapertura en Windows.
  • Impone límites de tamaño y políticas de retención.
  • Consulta la documentación oficial de pathlib.

Conclusión

El módulo tempfile en Python elimina gran parte del trabajo peligroso del almacenamiento temporal. Genera nombres resistentes a colisiones, crea recursos de forma segura, ofrece limpieza automática y funciona de manera consistente en plataformas soportadas.

La clase adecuada depende de la integración: TemporaryFile para un flujo descartable, NamedTemporaryFile para herramientas que necesitan una ruta, SpooledTemporaryFile para equilibrar memoria y disco y TemporaryDirectory para procesos con varios archivos. Con context managers, límites, pruebas multiplataforma y limpieza predecible, el almacenamiento temporal deja de ser una fuente de fugas, fallos de permisos y errores de seguridad.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Relojes que representan zonas horarias internacionales con zoneinfo en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    zoneinfo en Python: zonas horarias

    Aprende zoneinfo en Python para convertir zonas, tratar horario de verano, fold, UTC y tzdata sin errores de programación.

    Ler mais

    Tempo de leitura: 7 minutos
    29/07/2026
    Icono de documentos duplicados que representa copias superficiales y profundas en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    copy en Python: copia superficial y profunda

    Aprende copy en Python para crear copias superficiales, profundas y reemplazar campos sin compartir objetos mutables por error.

    Ler mais

    Tempo de leitura: 7 minutos
    28/07/2026
    Monitor con búsqueda binaria y listas ordenadas en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    bisect en Python: listas siempre ordenadas

    Aprende bisect en Python para mantener listas ordenadas, localizar rangos, encontrar vecinos e insertar valores con búsqueda binaria.

    Ler mais

    Tempo de leitura: 9 minutos
    27/07/2026
    Desarrollador implementando una cola de prioridad con heapq en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    heapq en Python: colas de prioridad

    Aprende heapq en Python para crear colas de prioridad, encontrar valores mínimos y procesar tareas con heaps eficientes.

    Ler mais

    Tempo de leitura: 7 minutos
    26/07/2026
    Compactando arquivos ZIP automaticamente com Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear archivos ZIP con Python y zipfile

    Crea archivos ZIP con Python y zipfile: carpetas, filtros, arcname, compresión, contenido en memoria, verificación, hashes y backups seguros.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Como evitar KeyError usando defaultdict em Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    defaultdict en Python: evita KeyError y simplifica diccionarios

    Aprende defaultdict en Python para evitar KeyError, contar, agrupar, crear estructuras anidadas y compararlo con get, setdefault y Counter.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026