Introducción
En este laboratorio, aprenderá a manejar rutas de archivos y directorios en Python utilizando el módulo moderno pathlib. Aunque el módulo más antiguo os.path todavía es común, pathlib ofrece un enfoque orientado a objetos que hace que la manipulación de rutas sea más intuitiva y legible. Aprenderá a crear, inspeccionar, validar y manipular rutas, archivos y directorios de una manera que funciona en diferentes sistemas operativos como Windows, macOS y Linux.
Al finalizar este laboratorio, dominará:
- La unión correcta de componentes de ruta.
- La creación y gestión de directorios.
- La diferenciación entre rutas absolutas y relativas.
- La validación de la existencia y el tipo de rutas.
- La realización de operaciones comunes de archivos como copiar, mover y eliminar.
- El recorrido de árboles de directorios para encontrar archivos y carpetas.
Operaciones Básicas de Rutas
En este paso, aprenderá los fundamentos de la manipulación de rutas utilizando el módulo pathlib. Esto incluye unir componentes de ruta, obtener el directorio de trabajo actual y crear nuevos directorios.
El módulo pathlib proporciona una forma elegante y multiplataforma de manejar rutas del sistema de archivos. En Windows, las rutas utilizan barras invertidas (\), mientras que en sistemas tipo Unix (Linux, macOS), utilizan barras diagonales (/). Usar pathlib asegura que su código funcione en cualquier plataforma sin ajustes manuales.
Nota: Si no está familiarizado con el uso de WebIDE (similar a VS Code), por favor, aprenda primero en este laboratorio.
Primero, veamos cómo unir componentes de ruta. El operador / es un atajo intuitivo para joinpath().
- Abra el archivo
main.pydesde el explorador de archivos de la izquierda. - Reemplace el contenido de
main.pycon el siguiente código para unir componentes de ruta e imprimir el resultado.
from pathlib import Path
## Unir componentes de ruta usando el operador /
my_path = Path('usr') / 'bin' / 'spam'
print(my_path)
- Ejecute el script desde la terminal:
python3 main.py
Verá la siguiente salida, que demuestra cómo pathlib forma correctamente una ruta estilo Unix:
usr/bin/spam
A continuación, obtengamos el directorio de trabajo actual usando Path.cwd().
- Reemplace el contenido de
main.pycon el siguiente código (esto reemplaza el código anterior):
from pathlib import Path
## Obtener el directorio de trabajo actual
cwd = Path.cwd()
print(cwd)
- Ejecute el script nuevamente:
python3 main.py
La salida mostrará el directorio de trabajo actual, que es /home/labex/project en este entorno:
/home/labex/project
Finalmente, creemos un nuevo directorio. Ocurre un FileNotFoundError si intenta crear un directorio donde el directorio padre no existe. Para evitar esto, use mkdir(parents=True), que crea todos los directorios padres necesarios.
- Reemplace el contenido de
main.pycon el siguiente código para crear una estructura de directorios anidada:
from pathlib import Path
## Obtener el directorio de trabajo actual
cwd = Path.cwd()
## Definir la ruta para los nuevos directorios anidados
new_dirs = cwd / 'delicious' / 'walnut' / 'waffles'
## Crear los directorios, incluyendo cualquier padre faltante
new_dirs.mkdir(parents=True, exist_ok=True)
print(f"Successfully created: {new_dirs}")
El argumento
exist_ok=Truepreviene un error si el directorio ya existe. Esto significa que puede ejecutar el script varias veces sin errores.
- Ejecute el script:
python3 main.py
El script creará los directorios anidados e imprimirá un mensaje de confirmación:
Successfully created: /home/labex/project/delicious/walnut/waffles
Puede verificar la creación del directorio ejecutando ls -R delicious en la terminal.
Rutas Absolutas vs. Relativas
En este paso, aprenderá a distinguir y trabajar con rutas absolutas y relativas.
- Una ruta absoluta comienza desde la raíz del sistema de archivos (ej.
/en Linux oC:\en Windows). - Una ruta relativa se define desde el directorio de trabajo actual.
pathlib proporciona métodos para verificar si una ruta es absoluta, resolver una ruta a su forma absoluta y encontrar una ruta relativa desde un punto de partida.
Primero, veamos cómo verificar si una ruta es absoluta usando is_absolute().
- Reemplace el contenido de
main.pycon el siguiente código:
from pathlib import Path
## Verificar si las rutas son absolutas
print(f"Path('/') is absolute: {Path('/').is_absolute()}")
print(f"Path('..') is absolute: {Path('..').is_absolute()}")
- Ejecute el script:
python3 main.py
La salida confirma que / es una ruta absoluta, mientras que .. (directorio padre) es relativa.
Path('/') is absolute: True
Path('..') is absolute: False
A continuación, puede obtener la ruta absoluta completa de una ruta relativa usando resolve(). Esto es útil para convertir rutas relativas como . (directorio actual) o .. (directorio padre) a su forma completa e inequívoca.
- Reemplace el contenido de
main.pycon el siguiente código:
from pathlib import Path
## Resolver una ruta relativa a su forma absoluta
## '..' se refiere al directorio padre del directorio de trabajo actual
resolved_path = Path('..').resolve()
print(f"Current working directory: {Path.cwd()}")
print(f"Resolved path of '..': {resolved_path}")
- Ejecute el script:
python3 main.py
La salida mostrará el directorio actual y la ruta absoluta resuelta de su padre.
Current working directory: /home/labex/project
Resolved path of '..': /home/labex
Finalmente, puede calcular una ruta relativa de una ruta a otra usando relative_to().
- Reemplace el contenido de
main.pycon el siguiente código para calcular una ruta relativa:
from pathlib import Path
## Obtener una ruta relativa desde un punto de partida
## Esto muestra la ruta a 'passwd' relativa al directorio raíz '/'
relative_path = Path('/etc/passwd').relative_to('/')
print(f"Path to '/etc/passwd' relative to '/': {relative_path}")
- Ejecute el script:
python3 main.py
La salida muestra la ruta relativa al directorio raíz:
Path to '/etc/passwd' relative to '/': etc/passwd
Validación e Inspección de Rutas
En este paso, aprenderá a verificar las propiedades de una ruta, como si existe y si es un archivo o un directorio. También aprenderá a recuperar metadatos de archivos como su tamaño.
Una tarea común es verificar si un archivo o directorio existe antes de intentar acceder a él. El método exists() es perfecto para esto.
- Abra
main.pyy reemplace su contenido con el siguiente código. Esto verificará la existencia del directorio actual (.), un archivo (setup.py) y un archivo inexistente.
from pathlib import Path
## Verificar si las rutas existen
print(f"Path('.') exists: {Path('.').exists()}")
print(f"Path('setup.py') exists: {Path('setup.py').exists()}")
print(f"Path('nonexistentfile') exists: {Path('nonexistentfile').exists()}")
- Ejecute el script:
python3 main.py
La salida confirmará qué rutas existen:
Path('.') exists: True
Path('setup.py') exists: True
Path('nonexistentfile') exists: False
También puede ser más específico y verificar si una ruta apunta a un archivo con is_file() o a un directorio con is_dir().
- Reemplace el contenido de
main.pycon el siguiente código para realizar estas comprobaciones:
from pathlib import Path
## Verificar si una ruta es un archivo
print(f"Path('setup.py').is_file(): {Path('setup.py').is_file()}")
print(f"Path('/home').is_file(): {Path('/home').is_file()}")
## Verificar si una ruta es un directorio
print(f"Path('/').is_dir(): {Path('/').is_dir()}")
print(f"Path('setup.py').is_dir(): {Path('setup.py').is_dir()}")
- Ejecute el script:
python3 main.py
La salida identificará correctamente el tipo de cada ruta:
Path('setup.py').is_file(): True
Path('/home').is_file(): False
Path('/').is_dir(): True
Path('setup.py').is_dir(): False
Finalmente, para obtener información detallada del archivo, como su tamaño, puede usar el método stat(). Devuelve un objeto con varios atributos, incluido st_size para el tamaño del archivo en bytes.
- Reemplace el contenido de
main.pycon el siguiente código para obtener el tamaño de un archivo del sistema:
from pathlib import Path
import os
## Definir la ruta a un archivo
file_path = Path('/bin/python3')
## Obtener estadísticas del archivo
stat_info = file_path.stat()
## Imprimir el tamaño en bytes
print(f"File: {file_path}")
print(f"Size: {stat_info.st_size} bytes")
- Ejecute el script:
python3 main.py
La salida mostrará el tamaño del ejecutable de Python en bytes. El tamaño exacto puede variar.
File: /bin/python3
Size: 10024 bytes
Gestión de Archivos y Carpetas
En este paso, aprenderá a realizar operaciones comunes del sistema de archivos como copiar, mover, renombrar y eliminar archivos y carpetas utilizando el módulo shutil en combinación con pathlib.
El módulo shutil proporciona funciones de alto nivel para operaciones de archivos. Comencemos con la copia de archivos. shutil.copy() copia un único archivo a una nueva ubicación.
- Abra el archivo
manage_files.pydesde el explorador de archivos de la izquierda. - Reemplace el contenido de
manage_files.pycon el siguiente código. Esto copiaráspam.txtal directorio/tmp/delicious.
import shutil
from pathlib import Path
## Definir origen y destino
source_file = Path('/tmp/spam.txt')
destination_dir = Path('/tmp/delicious')
## Copiar el archivo
shutil.copy(source_file, destination_dir)
print(f"Copied '{source_file}' to '{destination_dir}'")
## También puede renombrar el archivo mientras lo copia
shutil.copy('/tmp/eggs.txt', '/tmp/delicious/eggs2.txt')
print("Copied and renamed 'eggs.txt' to 'eggs2.txt'")
- Ejecute el script:
python3 manage_files.py
Para copiar un árbol de directorios completo, use shutil.copytree().
- Agregue las siguientes líneas al final de
manage_files.py(añádalas después del código existente):
## Copiar un árbol de directorios completo
shutil.copytree('/tmp/bacon', '/tmp/bacon_backup')
print("Copied directory '/tmp/bacon' to '/tmp/bacon_backup'")
Nota: Si ejecuta este script varias veces,
shutil.copytree()fallará porque el directorio de destino ya existe. Este es el comportamiento esperado. Por ahora, ejecútelo solo una vez.
- Ejecute el script nuevamente para verlo en acción.
A continuación, veamos cómo mover y renombrar archivos con shutil.move(). Esta función puede mover un archivo a un directorio diferente o renombrarlo.
- Reemplace el contenido completo de
manage_files.pycon el siguiente código para moverbacon.txt:
import shutil
from pathlib import Path
## Crear el directorio de destino si no existe
Path('/tmp/eggs').mkdir(parents=True, exist_ok=True)
## Mover un archivo a un directorio (solo si el origen existe)
bacon_source = Path('/tmp/bacon.txt')
if bacon_source.exists():
shutil.move('/tmp/bacon.txt', '/tmp/eggs')
print("Moved '/tmp/bacon.txt' to '/tmp/eggs'")
else:
print("'/tmp/bacon.txt' not found (may have been moved already)")
## Mover y renombrar un archivo
## Primero, recreemos el archivo para moverlo
Path('/tmp/bacon.txt').touch()
shutil.move('/tmp/bacon.txt', '/tmp/eggs/new_bacon.txt')
print("Moved and renamed '/tmp/bacon.txt' to '/tmp/eggs/new_bacon.txt'")
Nota: El código verifica si el archivo de origen existe antes de moverlo, por lo que puede ejecutar este script varias veces de forma segura. La segunda parte siempre creará un nuevo archivo y lo moverá.
- Ejecute el script.
Finalmente, veamos la eliminación de archivos y carpetas.
Path.unlink()elimina un único archivo.Path.rmdir()elimina un directorio vacío.shutil.rmtree()elimina un directorio y todo su contenido.
- Reemplace el contenido completo de
manage_files.pycon lo siguiente:
from pathlib import Path
import shutil
## Crear un archivo para eliminar
file_to_delete = Path('/tmp/deleteme.txt')
file_to_delete.touch()
print(f"Created '{file_to_delete}'")
## Eliminar el archivo
file_to_delete.unlink()
print(f"Deleted '{file_to_delete}'")
## Crear un directorio para eliminar
dir_to_delete = Path('/tmp/temp_dir')
dir_to_delete.mkdir(exist_ok=True)
## rmdir() solo funciona en directorios vacíos
dir_to_delete.rmdir()
print(f"Deleted empty directory '{dir_to_delete}'")
## Usar shutil.rmtree() para eliminar un directorio y su contenido
## Nota: Esto fallará si el directorio no existe, lo cual está bien para este ejemplo
if Path('/tmp/bacon_backup').exists():
shutil.rmtree('/tmp/bacon_backup')
print("Deleted directory '/tmp/bacon_backup' and all its contents")
else:
print("Directory '/tmp/bacon_backup' does not exist (may have been deleted already)")
Nota: Si ejecuta este script varias veces, algunas operaciones pueden fallar porque los archivos o directorios ya han sido eliminados. Esto es normal y demuestra que estas operaciones no son idempotentes (no se pueden repetir de forma segura).
- Ejecute el script para realizar las operaciones de eliminación.
Recorrido de Directorios
En este paso, aprenderás cómo listar el contenido de un directorio y recorrer recursivamente un árbol de directorios.
Para listar el contenido de un directorio, puedes usar el método iterdir(), que devuelve un iterador de todos los elementos (archivos y directorios) en la ruta.
- Primero, configuremos una estructura de directorio de ejemplo. Ejecuta este comando en la terminal:
mkdir -p ~/project/data/level1 && touch ~/project/data/file0.txt ~/project/data/level1/file1.txt
- Ahora, abre
main.pyy reemplaza su contenido con el siguiente código para listar el contenido del directorio/usr/bin.
from pathlib import Path
## Listar contenido de un directorio
print("Contenido de '/usr/bin':")
count = 0
for f in Path('/usr/bin').iterdir():
if count < 5: ## Imprimir los primeros 5 elementos para mantener la salida corta
print(f)
count += 1
else:
break
- Ejecuta el script:
python3 main.py
La salida mostrará los primeros archivos y directorios dentro de /usr/bin. La lista exacta puede variar.
Contenido de '/usr/bin':
/usr/bin/[
/usr/bin/addpart
/usr/bin/apt
/usr/bin/apt-cache
/usr/bin/apt-cdrom
Puedes combinar iterdir() con stat() para calcular el tamaño total de todos los archivos en un directorio.
- Reemplaza el contenido de
main.pycon el siguiente código. Ten en cuenta que este código solo suma los tamaños de los hijos directos y no recursa en subdirectorios.
from pathlib import Path
total_size = 0
directory = Path('/usr/bin')
for sub_path in directory.iterdir():
if sub_path.is_file(): ## Asegurar que solo sumamos el tamaño de los archivos
total_size += sub_path.stat().st_size
print(f"Tamaño total de archivos en '{directory}': {total_size} bytes")
- Ejecuta el script. Imprimirá el tamaño total de todos los archivos directamente dentro de
/usr/bin.
Para tareas más complejas, es posible que necesites "recorrer" (walk) un árbol de directorios completo, visitando todos los subdirectorios y archivos. El método rglob() es perfecto para esto. Busca recursivamente todas las rutas que coincidan con un patrón específico. Usar * como patrón coincide con todo.
- Primero, crea una estructura de directorio más compleja para este ejemplo. Ejecuta esto en la terminal:
mkdir -p /tmp/delicious/cats /tmp/delicious/walnut/waffles
touch /tmp/delicious/spam.txt /tmp/delicious/cats/catnames.txt /tmp/delicious/walnut/waffles/butter.txt
Nota: Puedes ejecutar estos comandos varias veces de forma segura. El comando
mkdir -pno fallará si los directorios ya existen, ytouchactualizará las marcas de tiempo de los archivos si ya existen.
- Reemplaza el contenido de
main.pycon el siguiente código para recorrer el directorio/tmp/delicious:
from pathlib import Path
p = Path('/tmp/delicious')
print(f"Recorriendo el árbol de directorios para: {p}")
for i in p.rglob('*'):
print(i)
- Ejecuta el script:
python3 main.py
La salida listará cada archivo y carpeta dentro de /tmp/delicious y sus subdirectorios, demostrando cómo rglob() recorre todo el árbol.
Recorriendo el árbol de directorios para: /tmp/delicious
/tmp/delicious/spam.txt
/tmp/delicious/eggs2.txt
/tmp/delicious/cats
/tmp/delicious/walnut
/tmp/delicious/cats/catnames.txt
/tmp/delicious/walnut/waffles
/tmp/delicious/walnut/waffles/butter.txt
Resumen
¡Felicidades por completar el laboratorio! Ha aprendido a gestionar eficazmente las rutas de archivos y directorios en Python utilizando el módulo moderno pathlib.
A lo largo de este laboratorio, ha practicado:
- Crear y unir rutas de manera multiplataforma utilizando objetos
Pathy el operador/. - Obtener el directorio de trabajo actual y crear directorios anidados con
mkdir(parents=True). - Diferenciar entre rutas absolutas y relativas y convertir entre ellas usando
is_absolute(),resolve()yrelative_to(). - Validar rutas con
exists(),is_file()eis_dir(), e inspeccionar metadatos de archivos constat(). - Realizar tareas esenciales de gestión de archivos como copiar, mover y eliminar con el módulo
shutily los métodos depathlib. - Recorrer estructuras de directorios para listar contenidos con
iterdir()y encontrar elementos recursivamente conrglob().
Estas habilidades son fundamentales para escribir aplicaciones Python robustas y mantenibles que interactúan con el sistema de archivos.



