Cuando tus scripts cambian de ubicación dentro de un proyecto, las rutas relativas se rompen. La solución profesional consiste en definir un punto raíz desde el cual construir todas las rutas, sin importar dónde se encuentre el archivo que las ejecuta. Dos librerías de Python resuelven esto de forma elegante y, además, puedes crear funciones atajo —shortcuts— para acceder a los directorios que más utilizas en ciencia de datos.
¿Cómo establecer la raíz del proyecto con pyprojroot y pyhere?
El problema central es sencillo: si mueves un notebook a otra carpeta, las referencias con .. (dos puntos para retroceder) dejan de funcionar [0:30]. Para evitarlo existen al menos dos librerías que detectan automáticamente dónde comienza tu proyecto.
¿Qué hace pyprojroot y cómo se usa?
pyprojroot expone una función llamada here() que devuelve un objeto PosixPath de Pathlib apuntando a la carpeta raíz del proyecto [0:52]. A partir de ahí construyes la ruta con joinpath:
python
from pyprojroot import here
ruta_datos = here().joinpath("data", "raw")
print(ruta_datos)
- No necesitas usar
.. para retroceder directorios.
- Si mueves tu notebook a cualquier subcarpeta, la ruta sigue funcionando.
- Solo tendrías que editarla si cambias de lugar los propios datos, algo poco frecuente [1:30].
¿Cómo funciona pyhere como alternativa?
pyhere ofrece también una función here() que regresa un PosixPath [1:45]. La diferencia es que puede devolver una ruta con .., por lo que conviene llamar a .resolve() para obtener la ruta absoluta:
python
from pyhere import here
print(here().resolve()) # Ruta absoluta a la raíz del proyecto
Además, pyhere admite una sintaxis alternativa con el operador / para unir segmentos, igual de válida que joinpath [2:10]:
python
ruta = here().resolve() / "data" / "raw"
Ambas formas son correctas. Lo importante es que el resultado sea legible y que definas una raíz clara para tu proyecto.
¿Cómo crear funciones atajo para acceder a directorios frecuentes?
En ciencia de datos accedes constantemente a carpetas como data/raw, data/processed o notebooks. Repetir la construcción de esas rutas una y otra vez resulta tedioso [2:40]. La solución es crear una función generadora de atajos.
¿Qué es una función que devuelve otra función en este contexto?
Este patrón se conoce como closure: una función externa crea y retorna una función interna que "recuerda" el directorio base [3:00].
python
from pyprojroot import here
def mkdir_function(dir_name):
def dir_function(*args):
return here().joinpath(dir_name, *args)
return dir_function
dir_name fija la carpeta principal (por ejemplo, "data").
*args permite pasar un número ilimitado de subcarpetas o archivos adicionales.
- La función regresada actúa como un shortcut reutilizable.
Para usarla basta con asignarla a una variable descriptiva [3:50]:
python
data_dir = mkdir_function("data")
Acceder a data/raw/pathlib/jeep.kip
print(data_dir("raw", "pathlib", "jeep.kip").exists()) # True
El mismo patrón aplica para cualquier otra carpeta del proyecto:
python
notebooks_dir = mkdir_function("notebooks")
print(notebooks_dir()) # Ruta completa a la carpeta notebooks
Con estas funciones el código queda explícito: al leer data_dir("raw", "pathlib") sabes exactamente a qué carpeta te refieres sin revisar la estructura de directorios [4:30].
¿Por qué enraizar el proyecto mejora la portabilidad?
Al combinar Pathlib con una raíz definida por pyprojroot o pyhere, obtienes dos ventajas fundamentales [5:00]:
- Independencia del sistema operativo: las rutas se construyen correctamente en Windows, macOS y Linux.
- Independencia de la ubicación: puedes mover el proyecto completo a otra computadora o a otro directorio y todo seguirá funcionando.
Esto significa que tus notebooks y scripts son completamente portables. Solo necesitas mantener la estructura interna del proyecto coherente.
Si ya dominas la construcción de rutas con Pathlib, la creación de una raíz con estas librerías y la generación de shortcuts, tienes las herramientas necesarias para que tu flujo de trabajo con archivos en Python sea robusto y profesional. ¿Qué otros atajos crearías para tu proyecto? Comparte tus ideas en los comentarios.