Módulo os de Python: Guía de Operaciones con Archivos y Directorios
Updated on
Cada script de Python que lee un archivo de configuración, guarda resultados, organiza datos o automatiza despliegues necesita interactuar con el sistema de archivos. Pero las rutas de archivos se comportan de manera diferente en Windows, macOS y Linux. Una ruta codificada como /home/user/data falla en Windows. Concatenar strings manualmente con + y / genera errores de doble barra y separadores faltantes. Y sin las verificaciones adecuadas, tu script podría eliminar el archivo equivocado o fallar cuando un directorio ya existe.
El módulo os de Python resuelve estos problemas. Proporciona una interfaz portable y multiplataforma para trabajar con el sistema operativo -- crear directorios, listar archivos, leer variables de entorno, manipular rutas y recorrer árboles de directorios. Viene incluido con cada instalación de Python, no requiere pip install y maneja las diferencias entre plataformas automáticamente.
Esta guía cubre cada función esencial del módulo os, organizada por caso de uso, con ejemplos prácticos que puedes copiar directamente en tus proyectos.
Obtener el Directorio de Trabajo Actual
Antes de hacer cualquier cosa con archivos, necesitas saber dónde se ejecuta tu script. os.getcwd() devuelve el directorio de trabajo actual como una ruta absoluta.
import os
# Obtener el directorio de trabajo actual
cwd = os.getcwd()
print(cwd) # e.g., /home/user/projects/myapp
# Cambiar el directorio de trabajo
os.chdir('/tmp')
print(os.getcwd()) # /tmp
# Volver al directorio anterior
os.chdir(cwd)Usa os.getcwd() cuando construyas rutas relativas o cuando necesites restaurar el directorio de trabajo después de cambiarlo temporalmente.
Operaciones con Directorios
Crear Directorios
os.mkdir() crea un único directorio. Lanza FileExistsError si el directorio ya existe y FileNotFoundError si el directorio padre no existe.
import os
# Crear un único directorio
os.mkdir('output')
# Crear solo si no existe
if not os.path.exists('output'):
os.mkdir('output')os.makedirs() crea directorios de forma recursiva -- incluyendo todos los directorios padre faltantes. El parámetro exist_ok=True evita errores cuando el directorio ya existe.
import os
# Crear directorios anidados en una sola llamada
os.makedirs('data/raw/2026/january', exist_ok=True)
# Sin exist_ok, esto lanza FileExistsError si 'data' ya existe
# os.makedirs('data/raw/2026/january') # puede lanzar errorListar Contenido de Directorios
os.listdir() devuelve una lista de todas las entradas (archivos y directorios) en una ruta dada.
import os
# Listar todo en el directorio actual
entries = os.listdir('.')
print(entries) # ['main.py', 'data', 'output', 'README.md']
# Listar contenido de un directorio específico
data_files = os.listdir('/var/log')
print(data_files)os.scandir() es una alternativa más eficiente que devuelve objetos DirEntry con atributos de archivo almacenados en caché. Úsalo cuando necesites metadatos de archivos junto con los nombres.
import os
with os.scandir('.') as entries:
for entry in entries:
info = entry.stat()
print(f"{entry.name:30s} {'DIR' if entry.is_dir() else 'FILE':4s} {info.st_size} bytes")Eliminar Directorios
os.rmdir() elimina un directorio vacío. Para directorios no vacíos, usa shutil.rmtree() en su lugar.
import os
import shutil
# Eliminar un directorio vacío
os.rmdir('output')
# Eliminar un directorio y todo su contenido (usar con precaución)
shutil.rmtree('data/raw/2026')Operaciones con Archivos
Eliminar Archivos
os.remove() (o su alias os.unlink()) elimina un único archivo. Lanza FileNotFoundError si el archivo no existe.
import os
# Eliminar un archivo
os.remove('temp_output.csv')
# Eliminación segura con verificación de existencia
filepath = 'temp_output.csv'
if os.path.exists(filepath):
os.remove(filepath)
print(f"Eliminado {filepath}")
else:
print(f"{filepath} no encontrado")Renombrar y Mover Archivos
os.rename() renombra o mueve un archivo o directorio. Si el destino ya existe, el comportamiento depende de la plataforma -- puede sobrescribir en Unix pero lanzar un error en Windows. Usa os.replace() para reemplazo atómico garantizado.
import os
# Renombrar un archivo
os.rename('old_report.csv', 'new_report.csv')
# Mover un archivo a un directorio diferente
os.rename('report.csv', 'archive/report_2026.csv')
# Reemplazo atómico (sobrescribe destino en todas las plataformas)
os.replace('new_data.csv', 'data.csv')Obtener Información de Archivos
os.stat() devuelve metadatos detallados del archivo incluyendo tamaño, permisos y marcas de tiempo.
import os
from datetime import datetime
info = os.stat('data.csv')
print(f"Tamaño: {info.st_size} bytes")
print(f"Modificado: {datetime.fromtimestamp(info.st_mtime)}")
print(f"Creado: {datetime.fromtimestamp(info.st_ctime)}")
print(f"Permisos: {oct(info.st_mode)}")Operaciones de Rutas con os.path
El submódulo os.path es donde ocurre la mayor parte del trabajo diario con el sistema de archivos. Maneja la construcción, validación y descomposición de rutas entre plataformas.
Construir Rutas de Forma Segura
Nunca concatenes rutas con +. Usa os.path.join() para construir rutas correctamente independientemente del sistema operativo.
import os
# Correcto: os.path.join maneja separadores
path = os.path.join('data', 'raw', 'sales.csv')
print(path) # 'data/raw/sales.csv' en Unix, 'data\\raw\\sales.csv' en Windows
# Incorrecto: la concatenación de strings puede fallar
bad_path = 'data' + '/' + 'raw' + '/' + 'sales.csv' # falla en WindowsVerificar Existencia y Tipo
import os
# Verificar si una ruta existe (archivo o directorio)
print(os.path.exists('/etc/hosts')) # True (en Linux/macOS)
# Verificar específicamente un archivo
print(os.path.isfile('main.py')) # True
print(os.path.isfile('data')) # False (es un directorio)
# Verificar específicamente un directorio
print(os.path.isdir('data')) # True
print(os.path.isdir('main.py')) # FalseDescomponer Rutas
Extrae componentes de una ruta de archivo sin dividir strings manualmente.
import os
filepath = '/home/user/projects/report_final.csv'
# Obtener el nombre del archivo
print(os.path.basename(filepath)) # 'report_final.csv'
# Obtener el directorio
print(os.path.dirname(filepath)) # '/home/user/projects'
# Dividir en directorio y nombre de archivo
directory, filename = os.path.split(filepath)
print(directory) # '/home/user/projects'
print(filename) # 'report_final.csv'
# Dividir nombre de archivo y extensión
name, ext = os.path.splitext(filepath)
print(name) # '/home/user/projects/report_final'
print(ext) # '.csv'
# Obtener ruta absoluta de una ruta relativa
print(os.path.abspath('data.csv')) # '/home/user/projects/data.csv'
# Resolver directorio home del usuario
print(os.path.expanduser('~/Documents')) # '/home/user/Documents'Referencia Rápida de Operaciones de Rutas
| Función | Propósito | Ejemplo de Salida |
|---|---|---|
os.path.join('a', 'b.txt') | Construir ruta | 'a/b.txt' |
os.path.exists(path) | ¿Existe la ruta? | True / False |
os.path.isfile(path) | ¿Es un archivo? | True / False |
os.path.isdir(path) | ¿Es un directorio? | True / False |
os.path.basename(path) | Solo nombre de archivo | 'report.csv' |
os.path.dirname(path) | Solo directorio | '/home/user' |
os.path.splitext(path) | Dividir nombre + extensión | ('report', '.csv') |
os.path.abspath(path) | Ruta absoluta | '/full/path/to/file' |
os.path.getsize(path) | Tamaño del archivo en bytes | 4096 |
os.path.expanduser('~') | Directorio home | '/home/user' |
Variables de Entorno
El módulo os proporciona acceso directo a las variables de entorno del sistema -- esencial para leer configuración, claves API y configuraciones de despliegue.
import os
# Leer una variable de entorno (devuelve None si no está configurada)
db_host = os.getenv('DATABASE_HOST')
print(db_host)
# Leer con un valor predeterminado
db_port = os.getenv('DATABASE_PORT', '5432')
print(db_port) # '5432' si DATABASE_PORT no está configurado
# Acceso mediante diccionario os.environ (lanza KeyError si falta)
try:
secret = os.environ['API_SECRET']
except KeyError:
print("API_SECRET no configurado")
# Establecer una variable de entorno (para procesos hijos)
os.environ['APP_MODE'] = 'production'
# Listar todas las variables de entorno
for key, value in os.environ.items():
print(f"{key}={value}")La diferencia entre os.getenv() y os.environ[] importa: getenv devuelve None (o un valor predeterminado) cuando la variable falta, mientras que os.environ[] lanza un KeyError. Usa getenv para configuración opcional y os.environ para configuraciones requeridas que deben fallar ruidosamente cuando están ausentes.
Recorrer Árboles de Directorios con os.walk
os.walk() recorre recursivamente un árbol de directorios, generando una tupla de 3 elementos (dirpath, dirnames, filenames) por cada directorio que visita.
import os
# Recorrer un directorio de proyecto
for dirpath, dirnames, filenames in os.walk('/home/user/project'):
# Omitir directorios ocultos
dirnames[:] = [d for d in dirnames if not d.startswith('.')]
print(f"\nDirectorio: {dirpath}")
print(f" Subdirectorios: {dirnames}")
print(f" Archivos: {filenames}")La modificación in-place de dirnames[:] controla en qué subdirectorios entra os.walk. Este es un patrón poderoso para omitir directorios .git, __pycache__ o node_modules.
Calcular el Tamaño Total de un Directorio
import os
def get_directory_size(path):
total = 0
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
# Omitir enlaces simbólicos
if not os.path.islink(filepath):
total += os.path.getsize(filepath)
return total
size_bytes = get_directory_size('/home/user/project')
size_mb = size_bytes / (1024 * 1024)
print(f"Tamaño total: {size_mb:.2f} MB")Patrones Comunes
Encontrar Todos los Archivos por Extensión
import os
def find_files(directory, extension):
"""Encontrar recursivamente todos los archivos con una extensión dada."""
matches = []
for dirpath, dirnames, filenames in os.walk(directory):
for filename in filenames:
if filename.endswith(extension):
matches.append(os.path.join(dirpath, filename))
return matches
# Encontrar todos los archivos Python
python_files = find_files('/home/user/project', '.py')
for f in python_files:
print(f)
# Encontrar todos los archivos de datos CSV
csv_files = find_files('data', '.csv')
print(f"Se encontraron {len(csv_files)} archivos CSV")Crear una Estructura de Salida Anidada
import os
def setup_project_dirs(base_path):
"""Crear una estructura de directorios de proyecto estándar."""
dirs = [
'data/raw',
'data/processed',
'data/output',
'logs',
'config',
'reports/figures',
]
for d in dirs:
full_path = os.path.join(base_path, d)
os.makedirs(full_path, exist_ok=True)
print(f"Creado: {full_path}")
setup_project_dirs('my_project')Operaciones Seguras con Archivos Temporales
import os
import tempfile
# Crear un archivo temporal que se elimina automáticamente
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp:
tmp.write('col1,col2\n1,2\n3,4\n')
tmp_path = tmp.name
print(f"Archivo temporal: {tmp_path}")
print(f"Existe: {os.path.exists(tmp_path)}")
# Limpiar
os.remove(tmp_path)os.path vs pathlib: ¿Cuál Deberías Usar?
Python 3.4 introdujo pathlib como alternativa orientada a objetos de os.path. Ambos funcionan, pero tienen diferentes fortalezas.
| Característica | os.path | pathlib |
|---|---|---|
| Estilo | Funcional (basado en strings) | Orientado a objetos |
| Disponible desde | Python 2 | Python 3.4+ |
| Concatenación de rutas | os.path.join('a', 'b') | Path('a') / 'b' |
| Verificar existencia | os.path.exists(p) | p.exists() |
| Leer archivo | open(os.path.join(d, f)) | Path(d, f).read_text() |
| Patrones glob | import glob; glob.glob(...) | Path('.').glob('*.py') |
| Glob recursivo | os.walk() + filtro | Path('.').rglob('*.py') |
| Extensión del archivo | os.path.splitext(f)[1] | p.suffix |
| Nombre base del archivo | os.path.splitext(os.path.basename(f))[0] | p.stem |
| Multiplataforma | Sí | Sí |
| Compatibilidad con terceros | Universal | La mayoría de bibliotecas aceptan objetos Path |
Cuándo usar os.path: Bases de código heredadas, scripts que deben soportar Python 2, o cuando trabajas con bibliotecas que solo aceptan rutas como strings.
Cuándo usar pathlib: Proyectos nuevos, cuando quieres una sintaxis más limpia, o cuando encadenas múltiples operaciones de rutas.
# Enfoque con os.path
import os
config_path = os.path.join(os.path.expanduser('~'), '.config', 'myapp', 'settings.json')
if os.path.isfile(config_path):
with open(config_path) as f:
data = f.read()
# Enfoque con pathlib
from pathlib import Path
config_path = Path.home() / '.config' / 'myapp' / 'settings.json'
if config_path.is_file():
data = config_path.read_text()Ambos enfoques son válidos. El módulo os no está obsoleto y sigue siendo el estándar para operaciones a nivel de proceso, variables de entorno y llamadas al sistema de bajo nivel. pathlib simplemente ofrece una API más ergonómica para la manipulación de rutas.
Consideraciones Multiplataforma
El módulo os se adapta automáticamente al sistema operativo actual, pero hay detalles que vale la pena conocer.
import os
# os.sep es el separador de rutas de la plataforma
print(os.sep) # '/' en Unix, '\\' en Windows
# os.linesep es el fin de línea de la plataforma
print(repr(os.linesep)) # '\n' en Unix, '\r\n' en Windows
# os.name identifica la familia del sistema operativo
print(os.name) # 'posix' en Linux/macOS, 'nt' en Windows
# os.path.join maneja separadores automáticamente
path = os.path.join('data', 'output', 'results.csv')
# 'data/output/results.csv' en Unix
# 'data\\output\\results.csv' en WindowsReglas clave para scripts multiplataforma:
- Siempre usa
os.path.join()en lugar de concatenación de strings con/o\\. - Usa
os.path.expanduser('~')en lugar de codificar/home/username. - Usa
os.linesepo abre archivos en modo texto (que maneja los finales de línea) en lugar de codificar\n. - Prueba tu lógica de rutas en ambas plataformas si tu script será compartido.
Automatizar Tareas del Sistema de Archivos con RunCell
Cuando trabajas con operaciones del sistema de archivos en Jupyter notebooks -- organizando conjuntos de datos, configurando estructuras de proyecto o auditando árboles de archivos -- RunCell (opens in a new tab) agrega una capa de agente de IA sobre tu entorno de notebook. Puedes describir lo que quieres ("encuentra todos los archivos CSV de más de 100 MB en este árbol de directorios y lístalos por tamaño") y RunCell genera y ejecuta el código del módulo os por ti, haciendo que las tareas repetitivas de gestión de archivos sean más rápidas.
FAQ
¿Qué es el módulo os en Python?
El módulo os es parte de la biblioteca estándar de Python. Proporciona funciones para interactuar con el sistema operativo, incluyendo manipulación de archivos y directorios, manejo de rutas, acceso a variables de entorno y gestión de procesos. Lo importas con import os -- no se necesita instalación.
¿Cuál es la diferencia entre os.path.join y la concatenación de strings para rutas?
os.path.join() usa automáticamente el separador de rutas correcto para el sistema operativo actual (/ en Unix, \ en Windows). La concatenación de strings con + requiere insertar separadores manualmente, lo que genera errores cuando el código se ejecuta en una plataforma diferente. Siempre usa os.path.join().
¿Cómo listo recursivamente todos los archivos en un directorio?
Usa os.walk() para recorrer un árbol de directorios. Genera tuplas (dirpath, dirnames, filenames) para cada directorio. Combínalo con os.path.join(dirpath, filename) para construir rutas completas para cada archivo.
¿Debería usar os.path o pathlib?
Para proyectos nuevos de Python 3, pathlib ofrece una sintaxis más limpia y legible con su API orientada a objetos. Sin embargo, os y os.path no están obsoletos y siguen siendo la opción correcta para variables de entorno (os.environ), operaciones de procesos y bases de código heredadas. Muchos proyectos usan ambos.
¿Cómo elimino de forma segura un archivo o directorio en Python?
Usa os.remove(path) para eliminar un archivo y os.rmdir(path) para eliminar un directorio vacío. Siempre verifica primero con os.path.exists(path) o envuelve la llamada en un bloque try/except para manejar FileNotFoundError. Para directorios no vacíos, usa shutil.rmtree(path).
Conclusión
El módulo os de Python es la base para cada operación del sistema de archivos que tus scripts realizarán. os.path.join() construye rutas de forma segura entre plataformas. os.makedirs() crea directorios anidados en una sola llamada. os.walk() recorre árboles de directorios completos. os.environ y os.getenv() manejan la configuración sin codificar secretos. Y os.stat() te proporciona metadatos detallados de archivos.
Para código con muchas rutas, considera combinar os con pathlib para una sintaxis más limpia. Pero el módulo os sigue siendo esencial -- es la forma estándar de interactuar con el sistema operativo en Python, y cada desarrollador Python debería conocer sus funciones principales.