pathlib y os
pathlib proporciona rutas orientadas a objetos (Path) para unir, leer, buscar (glob) y crear directorios (mkdir). os y os.path se mantienen para indicadores de bajo nivel, variables de entorno e identificadores de proceso; combine ambos en código de producción.
Receta
from pathlib import Path
root = Path(__file__).resolve().parent
config = root / "config" / "app.toml"
config.parent.mkdir(parents=True, exist_ok=True)
config.write_text("key = 'value'\n", encoding="utf-8")Cuándo usar esto:
- Construir rutas de archivos portátiles
- Recorrer directorios con
glob/rglob - Leer/escribir archivos de texto o binarios
- Comprobar la existencia y metadatos de archivos
- Entorno y directorio de trabajo actual (cwd) a través de
os.environ,os.getcwd
Ejemplo funcional
import os
from pathlib import Path
def find_py_files(src: Path, limit: int = 5) -> list[Path]:
return sorted(src.rglob("*.py"))[:limit]
def ensure_cache() -> Path:
cache = Path(os.environ.get("APP_CACHE", Path.home() / ".cache" / "demo"))
cache.mkdir(parents=True, exist_ok=True)
return cache
root = Path.cwd()
print("cwd", root)
print("archivos de ejemplo", find_py_files(root))
stamp = ensure_cache() / "last.run"
stamp.write_text("ok", encoding="utf-8")
print(stamp.read_text(encoding="utf-8"))Lo que esto demuestra:
- El operador
/une segmentos de ruta de forma portátil rglobbusca recursivamente desde la raízmkdir(parents=True, exist_ok=True)crea el árbol de directorios- Patrón de anulación de entorno para directorios configurables
Inmersión profunda
pathlib vs os.path
| Tarea | pathlib | os |
|---|---|---|
| Unir | base / "x" | os.path.join |
| Existe | p.exists() | os.path.exists |
| Entorno | - | os.environ |
| chmod | p.chmod | os.chmod |
Texto vs Binario
read_text/write_textnecesitan codificaciónread_bytespara imágenes, pickles, archivos
Trampas comunes
- Concatenación de rutas de cadena - falla en Windows. Solución: Objetos
Path. - Rutas relativas sin ancla - dependen de sorpresas del directorio de trabajo actual (cwd). Solución:
resolve()o pasar el directorio base. - glob en árboles enormes - inicio en frío lento. Solución: Acotar la raíz, usar la poda de
os.walk, o un índice dedicado. - Carrera TOCTOU (Time-of-check to time-of-use) -
existsfalla antes deopen. Solución:opencon EAFP (Easier to Ask for Forgiveness than Permission) otry/except. - Codificación faltante - mojibake (caracteres incorrectos) en Windows. Solución: Siempre
utf-8para texto a menos que se conozca la configuración regional.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| os.walk | Poda detallada | Glob simple es suficiente |
Módulo tempfile | Archivos temporales seguros | Directorio de caché fijo |
| shutil | Copiar/mover árbol | Archivo único con pathlib |
Preguntas frecuentes
¿Path vs str para APIs?
Acepte os.PathLike (Path | str) en funciones públicas; convierta internamente a Path.
¿Absoluto vs resolve?
resolve() sigue enlaces simbólicos y hace que la ruta sea absoluta; úselo antes de comparar rutas.
¿Directorio de inicio?
Path.home() o ~ se expanden a través de expanduser().
¿Eliminar árbol?
shutil.rmtree - pathlib no tiene eliminación recursiva hasta unlink/rmdir cuidadosos.
¿Observar el sistema de archivos?
No hay un buen observador en la biblioteca estándar; watchdog en PyPI en algunas plataformas; sondeo de glob para casos simples.
¿Mutación de os.environ?
Afecta a los procesos hijos; documente los efectos secundarios en herramientas de línea de comandos.
¿Enlaces simbólicos?
Comportamiento de is_symlink, readlink, resolve - conozca el sistema de archivos de su despliegue.
¿Pathlib es seguro para hilos (thread-safe)?
Los objetos Path son inmutables; el propio sistema de archivos puede tener condiciones de carrera; lo mismo que os.
¿Rutas Unicode?
Las rutas de Python 3 son str (unicode); aún tenga cuidado con la normalización NFC en macOS.
¿Django MEDIA_ROOT?
Configúrelo como ruta str; use Path en código nuevo dentro de Django para consistencia.
Relacionado
- subprocess - ejecutar comandos con rutas
- json & Serialization - leer archivos de configuración
- Standard Library Overview - mapa
- Files & I/O - fundamentos
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.