Path.walk() es una forma moderna de recorrer árboles de directorios con el módulo pathlib de Python. En cada paso devuelve el directorio actual, los nombres de los subdirectorios y los nombres de los archivos, manteniendo la ubicación actual como un objeto Path. Esto permite crear automatizaciones de archivos más legibles y portables.
Cómo funciona Path.walk
Cada iteración produce tres valores: el directorio actual, una lista de nombres de subdirectorios y una lista de nombres de archivos. Para obtener una ruta completa, combina el directorio con el nombre mediante el operador /.
from pathlib import Path
raiz = Path("proyecto")
for directorio, subdirs, archivos in raiz.walk():
for nombre in archivos:
ruta = directorio / nombre
print(ruta)Ventajas de pathlib
Los objetos Path ofrecen propiedades y métodos como suffix, stem, name, stat(), exists() e is_file(). Así se evita concatenar cadenas manualmente y depender de separadores específicos del sistema operativo.
También puedes consultar nuestras guías sobre importlib.resources, fileinput, linecache y contextlib.chdir.
Procesar archivos en flujo
En árboles grandes, conviene procesar cada archivo al encontrarlo en lugar de guardar todas las rutas en una lista. Este enfoque reduce el consumo de memoria y permite descartar elementos pronto.
for directorio, subdirs, archivos in Path("datos").walk():
for nombre in archivos:
procesar(directorio / nombre)Filtrar por extensión
Usa suffix.lower() para realizar comparaciones predecibles. Un conjunto es práctico cuando se aceptan varias extensiones.
permitidas = {".csv", ".json", ".parquet"}
for directorio, subdirs, archivos in Path("datos").walk():
for nombre in archivos:
ruta = directorio / nombre
if ruta.suffix.lower() in permitidas:
procesar(ruta)Recorrido descendente y ascendente
Con top_down=True, los directorios padres se visitan antes que sus hijos. Es el comportamiento predeterminado y permite excluir carpetas antes de entrar en ellas. Con top_down=False, los niveles más profundos aparecen primero, lo que puede ser útil para informes que dependen de los resultados de los hijos.
Excluir directorios
Cuando el recorrido es descendente, modifica la lista subdirs en el lugar para impedir que Python visite ubicaciones innecesarias.
ignoradas = {".git", ".venv", "node_modules", "__pycache__"}
for directorio, subdirs, archivos in Path("proyecto").walk():
subdirs[:] = [nombre for nombre in subdirs if nombre not in ignoradas]
for nombre in archivos:
print(directorio / nombre)La asignación al segmento completo conserva el objeto de lista utilizado por el recorrido. Crear otra variable local no modifica la travesía.
Tratamiento de errores
Durante el recorrido pueden aparecer errores de permisos, carpetas modificadas por otro proceso, unidades no disponibles y fallos de entrada o salida. El parámetro on_error recibe una función para registrar o gestionar la excepción.
def informar(error):
print(f"No se puede acceder a {error.filename}: {error}")
for directorio, subdirs, archivos in Path("espacio-trabajo").walk(on_error=informar):
passNo conviene ignorar silenciosamente todas las excepciones. Un inventario incompleto puede provocar decisiones incorrectas en copias de seguridad, migraciones o auditorías.
Enlaces simbólicos y ciclos
Seguir enlaces simbólicos de directorios puede sacar el recorrido de la raíz prevista o crear ciclos. Un enlace puede apuntar a un ancestro y repetir la misma zona. Antes de seguir enlaces, define una estrategia de rutas visitadas y decide si se permiten ubicaciones externas.
Calcular el tamaño total
Combina walk() con stat() para estimar el tamaño total de una estructura.
def tamano_total(raiz: Path) -> int:
total = 0
for directorio, subdirs, archivos in raiz.walk():
for nombre in archivos:
ruta = directorio / nombre
try:
info = ruta.stat()
total += info.st_size
except OSError:
continue
return totalEl resultado no es atómico. Los archivos pueden cambiar, desaparecer o crecer mientras se ejecuta el análisis. Debe interpretarse como una estimación operativa, salvo que el almacenamiento proporcione snapshots.
Buscar archivos grandes
Una tarea habitual consiste en localizar archivos superiores a un límite. Es más seguro generar primero un informe, revisar las rutas y decidir después qué acción corresponde.
limite = 500 * 1024 * 1024
for directorio, subdirs, archivos in Path("archivo").walk():
for nombre in archivos:
ruta = directorio / nombre
try:
if ruta.stat().st_size > limite:
print(ruta)
except OSError as error:
print(error)Path.walk frente a rglob
rglob() es conciso para búsquedas por patrón, por ejemplo *.py. walk() es más adecuado cuando necesitas excluir carpetas, controlar errores, elegir el orden de recorrido o tomar decisiones por directorio.
for ruta in Path("proyecto").rglob("*.py"):
print(ruta)Path.walk frente a os.walk
os.walk() sigue siendo fiable y compatible con muchas versiones. La principal ventaja de Path.walk() es su integración con la API orientada a objetos de pathlib. El código existente no necesita una migración inmediata, pero los proyectos nuevos pueden resultar más claros al conservar objetos Path.
Limitar la profundidad
No existe un parámetro directo de profundidad máxima, pero puedes calcular el nivel relativo a la raíz y vaciar subdirs al alcanzar el límite.
raiz = Path("datos")
maximo = 3
for directorio, subdirs, archivos in raiz.walk():
profundidad = len(directorio.relative_to(raiz).parts)
if profundidad >= maximo:
subdirs.clear()Buenas prácticas de rendimiento
Evita llamar varias veces a stat() para el mismo archivo. Excluye directorios lo antes posible, procesa elementos en flujo y utiliza comparaciones simples cuando sean suficientes. En sistemas de archivos de red, las consultas de metadatos pueden ser mucho más lentas.
Operaciones seguras
Los recorridos suelen formar parte de herramientas de mantenimiento. Antes de mover, sustituir o limpiar archivos, verifica que cada ruta permanezca dentro de la raíz autorizada. Separa descubrimiento y ejecución, genera registros y permite revisar el resultado. Los enlaces simbólicos y los cambios concurrentes requieren atención adicional.
Compatibilidad
Path.walk() solo está disponible en versiones recientes de Python. Comprueba la versión mínima del proyecto. Para entornos antiguos, utiliza os.walk() o una capa de compatibilidad.
Consulta la documentación oficial de pathlib y la documentación oficial de os.walk para conocer el comportamiento actualizado.
Diseñar un escáner reutilizable
Una herramienta robusta suele separar recorrido, selección, procesamiento e informe. La capa de recorrido descubre rutas. La capa de selección aplica reglas de extensión, tamaño o nombre. La capa de procesamiento realiza el trabajo. La capa de informe registra éxitos, elementos omitidos y errores.
Esta separación mejora las pruebas. Puedes verificar las reglas sin modificar archivos, sustituir el procesador por un objeto simulado y confirmar que los errores permanecen visibles.
Pruebas del recorrido
Utiliza directorios temporales en las pruebas automatizadas. Crea carpetas anidadas, nombres ignorados, extensiones con distintas mayúsculas y archivos que cambian. Cuando la plataforma lo permita, prueba enlaces simbólicos y fallos de permisos. Comprueba que el conjunto devuelto sea exactamente el esperado.
Errores frecuentes
Entre los errores habituales están tratar los nombres devueltos como rutas completas, olvidar modificar subdirs en el lugar, repetir llamadas a stat(), ocultar todas las excepciones, seguir enlaces sin protección contra ciclos y asumir que el árbol no cambia durante la ejecución.
Conclusión
Path.walk() ofrece una interfaz expresiva para recorrer árboles de directorios. Funciona especialmente bien con exclusión temprana, tratamiento explícito de errores, políticas cuidadosas para enlaces y procesamiento en flujo. Con estas prácticas, sirve como base para inventarios, copias de seguridad, pipelines de datos, validadores y herramientas de mantenimiento.







