Python
Obtener fácilmente todos los archivos de un directorio en Python: Guía para principiantes

Obtener fácilmente todos los archivos de un directorio en Python: Guía para principiantes

MoeNagy Dev

Comprendiendo las rutas de archivos

Rutas absolutas vs. Rutas relativas

En Python, puedes trabajar con rutas de archivos tanto absolutas como relativas. Una ruta absoluta es la ubicación completa e inequívoca de un archivo o directorio, comenzando desde la raíz del sistema de archivos. Por otro lado, una ruta relativa es una ruta que es relativa al directorio de trabajo actual o a una ubicación específica en el sistema de archivos.

Aquí tienes un ejemplo de cómo utilizar rutas absolutas y relativas en Python:

# Ruta absoluta
ruta_absoluta = "/Users/nombre_de_usuario/documentos/archivo.txt"
 
# Ruta relativa
ruta_relativa = "documentos/archivo.txt"

Puedes usar la función os.path.abspath() para convertir una ruta relativa en una ruta absoluta:

import os
 
ruta_relativa = "documentos/archivo.txt"
ruta_absoluta = os.path.abspath(ruta_relativa)
print(ruta_absoluta)
# Output: /Users/nombre_de_usuario/documentos/archivo.txt

Navegando por el sistema de archivos con Python

Los módulos os y os.path en Python proporcionan un conjunto de funciones para navegar por el sistema de archivos. Aquí tienes algunas funciones comúnmente utilizadas:

  • os.getcwd(): Devuelve el directorio de trabajo actual.
  • os.chdir(ruta): Cambia el directorio de trabajo actual a la ruta especificada.
  • os.path.join(ruta1, ruta2, ...): Une de manera inteligente uno o más componentes de ruta.
  • os.path.dirname(ruta): Devuelve el nombre del directorio de la ruta especificada.
  • os.path.basename(ruta): Devuelve el nombre base de la ruta especificada.

Ejemplo:

import os
 
# Obtener el directorio de trabajo actual
directorio_actual = os.getcwd()
print(directorio_actual)
 
# Cambiar el directorio de trabajo actual
os.chdir("/Users/nombre_de_usuario/documentos")
nuevo_directorio = os.getcwd()
print(nuevo_directorio)
 
# Unir rutas
ruta_archivo = os.path.join(nuevo_directorio, "archivo.txt")
print(ruta_archivo)
 
# Obtener el directorio y el nombre base
nombre_directorio = os.path.dirname(ruta_archivo)
nombre_base = os.path.basename(ruta_archivo)
print(nombre_directorio)
print(nombre_base)

Obteniendo una lista de archivos en un directorio

Utilizando la función os.listdir()

Para obtener una lista de archivos y directorios en un directorio específico, puedes utilizar la función os.listdir(). Esta función devuelve una lista de todos los elementos (archivos y directorios) en el directorio especificado.

Ejemplo:

import os
 
# Obtener la lista de archivos y directorios en el directorio actual
elementos = os.listdir(".")
print(elementos)

Filtrando la lista de archivos

Puedes filtrar la lista de archivos y directorios comprobando el tipo de cada elemento utilizando las funciones os.path.isfile() y os.path.isdir().

Ejemplo:

import os
 
# Obtener la lista de archivos y directorios en el directorio actual
elementos = os.listdir(".")
 
# Filtrar la lista para obtener solo los archivos
archivos = [elemento for elemento in elementos if os.path.isfile(elemento)]
print(archivos)
 
# Filtrar la lista para obtener solo los directorios
directorios = [elemento for elemento in elementos if os.path.isdir(elemento)]
print(directorios)

Manejo de subdirectorios

Recorriendo subdirectorios de manera recursiva

Para recorrer subdirectorios y obtener una lista de todos los archivos en un árbol de directorios, puedes utilizar un enfoque recursivo. Esto implica llamar a la misma función o lógica dentro de la función para manejar subdirectorios.

Ejemplo:

import os
 
def obtener_todos_los_archivos(directorio):
    todos_los_archivos = []
    for elemento in os.listdir(directorio):
        ruta_elemento = os.path.join(directorio, elemento)
        if os.path.isfile(ruta_elemento):
            todos_los_archivos.append(ruta_elemento)
        elif os.path.isdir(ruta_elemento):
            todos_los_archivos.extend(obtener_todos_los_archivos(ruta_elemento))
    return todos_los_archivos
 
# Obtener todos los archivos en el directorio actual y subdirectorios
todos_los_archivos = obtener_todos_los_archivos(".")
print(todos_los_archivos)

Identificar directorios vs. archivos

Puedes utilizar las funciones os.path.isfile() y os.path.isdir() para determinar si un elemento en el sistema de archivos es un archivo o un directorio.

Ejemplo:

import os
 
# Comprobar si una ruta es un archivo
if os.path.isfile("archivo.txt"):
    print("¡Es un archivo!")
else:
    print("No es un archivo.")
 
# Comprobar si una ruta es un directorio
if os.path.isdir("documentos"):
    print("¡Es un directorio!")
else:
    print("No es un directorio.")

Trabajando con la función os.walk()

Explorando la función os.walk()

La función os.walk() proporciona una forma más conveniente de recorrer de manera recursiva un árbol de directorios y obtener una lista de todos los archivos y directorios. Genera una tupla de 3 elementos para cada directorio en el árbol, a partir del directorio raíz (el primer argumento):

  1. El directorio raíz
  2. Una lista de los nombres de los subdirectorios en root (excluyendo '.' y '..')
  3. Una lista de los nombres de los archivos que no son directorios en root

Ejemplo:

import os
 
for raiz, directorios, archivos in os.walk("."):
    print(f"Directorio raíz: {raiz}")
    print(f"Subdirectorios: {directorios}")
    print(f"Archivos: {archivos}")
    print()

Personalizando el comportamiento de os.walk()

Puedes personalizar el comportamiento de os.walk() proporcionando argumentos adicionales:

  • topdown: Si es True, os.walk() visita los directorios en el orden en que aparecen en el árbol de directorios (el valor predeterminado es True).
  • onerror: Una función que se llama cuando os.walk() encuentra un error. La función debe aceptar un único argumento, una instancia de OSError.
  • followlinks: Si es True, os.walk() seguirá los enlaces simbólicos (el valor predeterminado es False).

Ejemplo:

import os
 
for raiz, directorios, archivos in os.walk(".", topdown=False, onerror=lambda err: print(f"Error: {err}"), followlinks=True):
    print(f"Directorio raíz: {raiz}")
    print(f"Subdirectorios: {directorios}")
    print(f"Archivos: {archivos}")
    print()

Filtrando archivos por extensión

Comprobando la extensión del archivo

Puedes comprobar la extensión de un archivo utilizando la función os.path.splitext(), la cual devuelve una tupla de 2 elementos que contiene la raíz y la extensión de la ruta.

Ejemplo:

import os
 
ruta_archivo = "documentos/archivo.txt"
raiz, ext = os.path.splitext(ruta_archivo)
print(f"Raíz: {raiz}")
print(f"Extensión: {ext}")

Creando una lista de archivos con una extensión específica

Puedes combinar la comprobación de la extensión de los archivos con las técnicas de recorrido de directorios para crear una lista de archivos con una extensión específica.

Ejemplo:

import os
 
def obtener_archivos_por_extension(directorio, extension):
    todos_los_archivos = []
    for raiz, dirs, archivos in os.walk(directorio):
        for archivo in archivos:
            if archivo.endswith(extension):
                ruta_archivo = os.path.join(raiz, archivo)
                todos_los_archivos.append(ruta_archivo)
    return todos_los_archivos
 
# Obtener todos los archivos .txt en el directorio actual y subdirectorios
archivos_txt = obtener_archivos_por_extension(".", ".txt")
print(archivos_txt)

Ordenando y Organizando la Lista de Archivos

Ordenando la Lista de Archivos

Puedes ordenar la lista de archivos basándote en varios criterios, como el nombre del archivo, el tamaño o la fecha de modificación. La función sorted() en Python te permite ordenar una lista de archivos.

Ejemplo:

import os
 
# Obtener la lista de archivos en el directorio actual
archivos = os.listdir(".")
 
# Ordenar los archivos por nombre
archivos_ordenados = sorted(archivos)
print(archivos_ordenados)
 
# Ordenar los archivos por tamaño
tamaños_archivos = [(archivo, os.path.getsize(archivo)) for archivo in archivos]
ordenados_por_tamaño = sorted(tamaños_archivos, key=lambda x: x[1])
print(ordenados_por_tamaño)

Agrupando Archivos por Extensión

Puedes agrupar los archivos por sus extensiones y crear un diccionario u otra estructura de datos similar para organizar los archivos.

Ejemplo:

import os
from collections import defaultdict
 
def agrupar_archivos_por_extension(directorio):
    grupos_archivos = defaultdict(list)
    for raiz, dirs, archivos in os.walk(directorio):
        for archivo in archivos:
            _, ext = os.path.splitext(archivo)
            ruta_archivo = os.path.join(raiz, archivo)
            grupos_archivos[ext].append(ruta_archivo)
    return grupos_archivos
 
# Agrupar los archivos en el directorio actual y subdirectorios
grupos_archivos = agrupar_archivos_por_extension(".")
for extension, archivos in grupos_archivos.items():
    print(f"{extension}: {archivos}")

Manejando Errores y Casos Especiales

Manejando Permisos y Problemas de Acceso

Al trabajar con el sistema de archivos, te puedes encontrar con problemas de permisos o acceso. Puedes utilizar un bloque try-except para manejar estos errores y proporcionar una gestión de errores adecuada.

Ejemplo:

import os
 
def obtener_informacion_archivo(ruta_archivo):
    try:
        tamaño_archivo = os.path.getsize(ruta_archivo)
        ultima_modificación = os.path.getmtime(ruta_archivo)
        return tamaño_archivo, ultima_modificación
    except OSError as e:
        print(f"Error al acceder al archivo {ruta_archivo}: {e}")
        return None, None
 
# Obtener la información del archivo
información_archivo = obtener_informacion_archivo("archivo.txt")
if información_archivo[0] is not None:
    tamaño_archivo, ultima_modificación = información_archivo
    print(f"Tamaño del archivo: {tamaño_archivo} bytes")
    print(f"Última modificación: {ultima_modificación}")

Manejando Enlaces Simbólicos y Otros Archivos Especiales

Los módulos os y os.path de Python pueden manejar varios tipos de archivos especiales, como enlaces simbólicos, tuberías nombradas y archivos de dispositivo. Puedes utilizar la función os.path.islink() para comprobar si un archivo es un enlace simbólico.

Ejemplo:

import os
 
def manejar_archivos_especiales(directorio):
    for raiz, dirs, archivos in os.walk(directorio):
        for archivo in archivos:
            ruta_archivo = os.path.join(raiz, archivo)
            if os.path.islink(ruta_archivo):
                print(f"Enlace simbólico: {ruta_archivo}")
            elif os.path.isfifo(ruta_archivo):
                print(f"Tubería nombrada: {ruta_archivo}")
            elif os.path.isdev(ruta_archivo):
                print(f"Archivo de dispositivo: {ruta_archivo}")
            else:
                print(f"Archivo regular: {ruta_archivo}")
 
# Manejar archivos especiales en el directorio actual y subdirectorios
manejar_archivos_especiales(".")

Estructuras de Datos

Listas

Las listas son una de las estructuras de datos más fundamentales en Python. Son colecciones ordenadas de elementos que pueden contener valores de diferentes tipos de datos, incluyendo números, cadenas de texto e incluso otras estructuras de datos como listas o diccionarios.

Aquí tienes un ejemplo de cómo crear una lista y realizar algunas operaciones comunes:

# Crear una lista
frutas = ['manzana', 'plátano', 'cereza']
 
# Acceder a elementos
print(frutas[0])  # Salida: 'manzana'
print(frutas[-1])  # Salida: 'cereza'
 
# Agregar elementos
frutas.append('naranja')
print(frutas)  # Salida: ['manzana', 'plátano', 'cereza', 'naranja']
 
# Eliminar elementos
frutas.remove('plátano')
print(frutas)  # Salida: ['manzana', 'cereza', 'naranja']
 
# Rebanado (slicing)
print(frutas[1:3])  # Salida: ['cereza', 'naranja']

Tuplas

Las tuplas son similares a las listas, pero son inmutables, lo que significa que no puedes modificar su contenido después de haberlas creado. Las tuplas se definen utilizando paréntesis () en lugar de corchetes [].

# Crear una tupla
punto = (2, 3)
print(punto)  # Salida: (2, 3)
 
# Acceder a elementos
print(punto[0])  # Salida: 2
print(punto[1])  # Salida: 3
 
# Desempaquetar una tupla
x, y = punto
print(x)  # Salida: 2
print(y)  # Salida: 3

Diccionarios

Los diccionarios son colecciones no ordenadas de pares clave-valor. Te permiten almacenar y recuperar datos rápidamente utilizando claves únicas.

# Crear un diccionario
persona = {
    'nombre': 'Juan Pérez',
    'edad': 30,
    'ciudad': 'Madrid'
}
 
# Acceder a valores
print(persona['nombre'])  # Salida: 'Juan Pérez'
print(persona['edad'])  # Salida: 30
 
# Agregar y modificar entradas
persona['email'] = 'juan.perez@example.com'
persona['edad'] = 31
print(persona)  # Salida: {'nombre': 'Juan Pérez', 'edad': 31, 'ciudad': 'Madrid', 'email': 'juan.perez@example.com'}
 
# Iterar sobre un diccionario
for clave, valor in persona.items():
    print(f"{clave}: {valor}")

Conjuntos

Los conjuntos son colecciones desordenadas de elementos únicos. Son útiles para realizar operaciones como la unión, la intersección y la diferencia.

# Crear un conjunto
colors = {'red', 'green', 'blue'}
print(colors)  # Salida: {'red', 'green', 'blue'}
 
# Agregar y eliminar elementos
colors.add('yellow')
colors.remove('green')
print(colors)  # Salida: {'red', 'blue', 'yellow'}
 
# Operaciones de conjunto
set1 = {1, 2, 3}
set2 = {2, 3, 4}
print(set1 | set2)  # Unión: {1, 2, 3, 4}
print(set1 & set2)  # Intersección: {2, 3}
print(set1 - set2)  # Diferencia: {1}

Control de flujo

Declaraciones condicionales

Las declaraciones condicionales, como if-else y if-elif-else, te permiten ejecutar bloques de código diferentes según ciertas condiciones.

# Declaración if-else
age = 18
if age >= 18:
    print("Eres adulto.")
else:
    print("Eres menor de edad.")
 
# Declaración if-elif-else
score = 85
if score >= 90:
    print("A")
elif score >= 80:
    print("B")
elif score >= 70:
    print("C")
else:
    print("D")

Bucles

Los bucles, como for y while, te permiten ejecutar repetidamente un bloque de código.

# Bucle for
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print(fruit)
 
# Bucle while
count = 0
while count < 5:
    print(count)
    count += 1

Comprensiones de lista

Las comprensiones de lista proporcionan una forma concisa de crear nuevas listas basadas en las existentes.

# Comprensión de lista
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares)  # Salida: [1, 4, 9, 16, 25]
 
# Comprensión de lista condicional
even_numbers = [x for x in numbers if x % 2 == 0]
print(even_numbers)  # Salida: [2, 4]

Funciones

Las funciones son bloques de código reutilizables que realizan una tarea específica. Pueden aceptar argumentos, devolver valores y ayudar a organizar tu código.

# Definir una función
def greet(name):
    print(f"Hola, {name}!")
 
# Llamar a la función
greet("Alice")  # Salida: Hola, Alice!
 
# Funciones con valores de retorno
def add_numbers(a, b):
    return a + b
 
result = add_numbers(3, 4)
print(result)  # Salida: 7

Módulos y paquetes

La extensa biblioteca estándar de Python y los paquetes de terceros proporcionan una gran cantidad de funcionalidades que puedes aprovechar en tus proyectos.

# Importar un módulo
import math
print(math.pi)  # Salida: 3.141592653589793
 
# Importar funciones específicas de un módulo
from math import sqrt, floor
print(sqrt(16))  # Salida: 4.0
print(floor(3.7))  # Salida: 3
 
# Importar un paquete
import datetime
print(datetime.datetime.now())  # Salida: 2023-04-24 12:34:56.789012

Manejo de excepciones

El manejo de excepciones te permite gestionar errores y situaciones inesperadas en tu código de manera elegante.

# Manejo de excepciones
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Error: División por cero.")
 
# Manejo de múltiples excepciones
try:
    int('abc')
except ValueError:
    print("Error: Formato de entero inválido.")

E/S de archivos

Python proporciona funciones y métodos integrados para leer y escribir archivos.

# Escribir en un archivo
with open('example.txt', 'w') as file:
    file.write("¡Hola, mundo!")
 
# Leer desde un archivo
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)  # Salida: ¡Hola, mundo!

Conclusión

En este tutorial de Python, has aprendido sobre varias estructuras de datos, control de flujo, funciones, módulos y paquetes, manejo de excepciones y E/S de archivos. Estos conceptos forman la base de la programación en Python y te ayudarán a escribir código más eficiente y fácil de mantener. Recuerda practicar regularmente y explorar el vasto ecosistema de bibliotecas y marcos de Python para ampliar tus conocimientos y habilidades.

MoeNagy Dev