Python
Explora rápidamente el directorio de Python: lista todos los archivos fácilmente

Explora rápidamente el directorio de Python: lista todos los archivos fácilmente

MoeNagy Dev

Explorando la lista de Python de todos los archivos en un directorio

Obteniendo el directorio de trabajo actual

Entendiendo el directorio de trabajo actual

El directorio de trabajo actual es el directorio en el que se está ejecutando tu script de Python. Es la ubicación predeterminada donde tu script buscará archivos y directorios, y donde creará nuevos archivos, a menos que especifiques explícitamente una ruta diferente.

Determinando el directorio de trabajo actual utilizando el módulo os

Para obtener el directorio de trabajo actual en Python, puedes utilizar la función os.getcwd() del módulo os:

import os
 
current_dir = os.getcwd()
print(f"El directorio de trabajo actual es: {current_dir}")

Esto imprimirá la ruta completa del directorio de trabajo actual en tu sistema.

Listando todos los archivos en un directorio

Utilizando la función os.listdir()

Para obtener una lista de todos los archivos y directorios en el directorio de trabajo actual, puedes utilizar la función os.listdir():

import os
 
files_and_dirs = os.listdir()
print(f"Contenido del directorio actual: {files_and_dirs}")

Esto devolverá una lista de todos los elementos (archivos y directorios) en el directorio de trabajo actual.

Manejando directorios vacíos

Si el directorio de trabajo actual está vacío, os.listdir() devolverá una lista vacía. Puedes verificar esta condición y manejarla en consecuencia:

import os
 
files_and_dirs = os.listdir()
if not files_and_dirs:
    print("El directorio actual está vacío.")
else:
    print(f"Contenido del directorio actual: {files_and_dirs}")

Ordenando la lista de archivos

Si deseas que la lista de archivos esté ordenada, puedes utilizar la función sorted():

import os
 
files_and_dirs = sorted(os.listdir())
print(f"Contenido ordenado del directorio actual: {files_and_dirs}")

Esto devolverá la lista de archivos y directorios en orden alfabético.

Manejando subdirectorios

Recorriendo recursivamente subdirectorios

Para listar todos los archivos y directorios, incluyendo los que se encuentran en los subdirectorios, puedes utilizar un enfoque recursivo. Esto implica llamar a la función os.listdir() para cada subdirectorio y construir la lista completa de archivos.

import os
 
def listar_todos_los_archivos(directorio):
    """
    Recorre de forma recursiva un directorio y sus subdirectorios,
    devolviendo una lista de todos los archivos.
    """
    lista_archivos = []
    for elemento in os.listdir(directorio):
        ruta_elemento = os.path.join(directorio, elemento)
        if os.path.isfile(ruta_elemento):
            lista_archivos.append(ruta_elemento)
        elif os.path.isdir(ruta_elemento):
            lista_archivos.extend(listar_todos_los_archivos(ruta_elemento))
    return lista_archivos
 
# Ejemplo de uso
todos_los_archivos = listar_todos_los_archivos(os.getcwd())
print(f"Todos los archivos en el directorio y los subdirectorios: {todos_los_archivos}")

Esta función listar_todos_los_archivos() recibe como entrada una ruta de directorio y devuelve una lista de todos los archivos de ese directorio y sus subdirectorios.

Distinguiendo entre archivos y directorios

Las funciones os.path.isfile() y os.path.isdir() se pueden utilizar para determinar si un elemento en la lista de directorios es un archivo o un directorio, respectivamente.

import os
 
for elemento in os.listdir(os.getcwd()):
    ruta_elemento = os.path.join(os.getcwd(), elemento)
    if os.path.isfile(ruta_elemento):
        print(f"{elemento} es un archivo.")
    elif os.path.isdir(ruta_elemento):
        print(f"{elemento} es un directorio.")
    else:
        print(f"{elemento} es un tipo desconocido.")

Este código recorrerá el contenido del directorio actual e imprimirá si cada elemento es un archivo, un directorio o un tipo desconocido.

Manejando archivos y directorios ocultos

Por defecto, os.listdir() incluirá archivos y directorios ocultos (aquellos que comienzan con un punto, por ejemplo, .archivo_oculto.txt o .directorio_oculto/). Si deseas excluir estos elementos, puedes filtrarlos:

import os
 
todos_los_elementos = os.listdir(os.getcwd())
elementos_visibles = [elemento for elemento in todos_los_elementos if not elemento.startswith(".")]
print(f"Archivos y directorios visibles: {elementos_visibles}")

Esto creará una nueva lista elementos_visibles que contiene solo los archivos y directorios no ocultos.

Trabajando con rutas de archivos

Construyendo rutas de archivos completas

Cuando trabajas con archivos en un directorio, a menudo necesitas la ruta de archivo completa, que incluye el directorio y el nombre del archivo. Puedes utilizar la función os.path.join() para construir la ruta completa:

import os
 
directorio = os.getcwd()
nombre_archivo = "ejemplo.txt"
ruta_completa = os.path.join(directorio, nombre_archivo)
print(f"La ruta de archivo completa es: {ruta_completa}")

Esto imprimirá la ruta de archivo completa, que incluye el directorio de trabajo actual y el nombre del archivo.

Uniendo nombres de directorio y archivo

La función os.path.join() también se puede utilizar para unir varios componentes de la ruta, como nombres de directorio y nombres de archivo:

import os
 
directorio1 = "documentos"
directorio2 = "informes"
nombre_archivo = "informe.pdf"
ruta_completa = os.path.join(directorio1, directorio2, nombre_archivo)
print(f"La ruta de archivo completa es: {ruta_completa}")

Esto creará la ruta "documentos/informes/informe.pdf".

Normalizando rutas de archivos

A veces, las rutas de archivos pueden contener elementos innecesarios o redundantes, como . (directorio actual) o .. (directorio padre). Puedes utilizar la función os.path.normpath() para normalizar la ruta y eliminar estos elementos:

import os
 
ruta_desordenada = "documentos/./informes/../imagenes/imagen.jpg"
ruta_normalizada = os.path.normpath(ruta_desordenada)
print(f"La ruta normalizada es: {ruta_normalizada}")

Esto imprimirá "documents/images/image.jpg", con los elementos innecesarios . y .. eliminados.

Filtrar la lista de archivos

Selección de archivos basada en extensiones de archivos

Si deseas filtrar la lista de archivos para incluir solo archivos con una extensión de archivo específica, puedes usar una comprensión de lista:

import os
 
todos_los_archivos = os.listdir(os.getcwd())
archivos_txt = [archivo for archivo in todos_los_archivos if archivo.endswith(".txt")]
print(f"Archivos de texto en el directorio actual: {archivos_txt}")

Esto creará una nueva lista archivos_txt que contiene solo los archivos con la extensión .txt.

Exclusión de archivos o directorios específicos

También puedes excluir archivos o directorios específicos de la lista. Por ejemplo, para excluir archivos o directorios que comienzan con un punto (elementos ocultos):

import os
 
todos_los_elementos = os.listdir(os.getcwd())
elementos_visibles = [elemento for elemento in todos_los_elementos if not elemento.startswith(".")]
print(f"Archivos y directorios visibles: {elementos_visibles}")

Uso de expresiones regulares para filtrado avanzado

Para requisitos de filtrado más complejos, puedes utilizar expresiones regulares. El módulo re en Python proporciona una forma poderosa de buscar patrones en cadenas. Aquí tienes un ejemplo de uso de una expresión regular para filtrar la lista de archivos:

import os
import re
 
todos_los_archivos = os.listdir(os.getcwd())
patron = r"^informe_\d{4}.txt$"
archivos_coincidentes = [archivo for archivo in todos_los_archivos if re.match(patron, archivo)]
print(f"Archivos que coinciden con el patrón: {archivos_coincidentes}")

Esto creará una lista archivos_coincidentes que contiene solo los archivos cuyos nombres coincidan con el patrón de expresión regular "^informe_\d{4}.txt$", que busca archivos que comiencen con "informe_", seguidos de cuatro dígitos y terminen con ".txt".

Mostrar información del archivo

Obtención del tamaño del archivo, fechas de creación/modificación

Puedes usar las funciones os.path.getsize() y os.path.getmtime() para obtener el tamaño y la hora de modificación de un archivo, respectivamente:

import os
from datetime import datetime
 
ruta_archivo = os.path.join(os.getcwd(), "ejemplo.txt")
tamano_archivo = os.path.getsize(ruta_archivo)
hora_modificacion = os.path.getmtime(ruta_archivo)
print(f"Tamaño del archivo: {tamano_archivo} bytes")
print(f"Última modificación: {datetime.fromtimestamp(hora_modificacion)}")

Esto imprimirá el tamaño del archivo en bytes y la última hora de modificación del archivo "ejemplo.txt".

Imprimir detalles del archivo de manera formateada

Puedes crear una función para imprimir los detalles del archivo de manera más organizada y legible:

import os
from datetime import datetime
 
def imprimir_info_archivo(ruta_archivo):
    """
    Imprime información detallada sobre un archivo, incluyendo su nombre, tamaño y hora de modificación.
    """
    nombre_archivo = os.path.basename(ruta_archivo)
    tamano_archivo = os.path.getsize(ruta_archivo)
    hora_modificacion = os.path.getmtime(ruta_archivo)
    print(f"Nombre de archivo: {nombre_archivo}")
    print(f"Tamaño del archivo: {tamano_archivo} bytes")
    print(f"Última modificación: {datetime.fromtimestamp(hora_modificacion)}")
 
# Ejemplo de uso
imprimir_info_archivo(os.path.join(os.getcwd(), "ejemplo.txt"))

Esto imprimirá el nombre del archivo, el tamaño y la última hora de modificación de manera formateada.

Manejo de errores y excepciones

Tratando problemas de permisos

Cuando trabajas con archivos y directorios, es posible que te encuentres con errores relacionados con los permisos. Puedes usar un bloque try-except para manejar estas excepciones:

import os
 
try:
    archivo_restringido = os.path.join(os.getcwd(), "restringido.txt")
    tamano_archivo = os.path.getsize(archivo_restringido)
    print(f"Tamaño del archivo: {tamano_archivo} bytes")
except PermissionError:
    print(f"Error: No tienes permiso para acceder a {archivo_restringido}")

Este código intentará obtener el tamaño del archivo "restringido.txt", y si se produce un PermissionError, imprimirá un mensaje de error.

Capturar y manejar excepciones OSError

El módulo os puede generar excepciones OSError para varios problemas relacionados con archivos y directorios. Puedes capturar y manejar estas excepciones:

import os
 
try:
    archivo_inexistente = os.path.join(os.getcwd(), "inexistente.txt")
    tamano_archivo = os.path.getsize(archivo_inexistente)
    print(f"Tamaño del archivo: {tamano_archivo} bytes")
except OSError as e:
    print(f"Error: {e}")

Este código intentará obtener el tamaño del archivo "inexistente.txt", y si se produce un OSError (por ejemplo, si el archivo no existe), imprimirá el mensaje de error.

Aplicaciones prácticas

Copias de seguridad y scripts de archivo

Puedes utilizar las técnicas de listado de archivos para crear scripts de copia de seguridad o archivo. Por ejemplo, puedes crear un script que comprima todos los archivos de un directorio y sus subdirectorios en un solo archivo ZIP.

import os
import zipfile
 
def copia_seguridad_directorio(directorio, nombre_zip):
    """
    Crea un archivo ZIP de todos los archivos en un directorio y sus subdirectorios.
    """
    with zipfile.ZipFile(nombre_zip, "w") as archivo_zip:
        for raiz, _, archivos in os.walk(directorio):
            for archivo in archivos:
                ruta_archivo = os.path.join(raiz, archivo)
                archivo_zip.write(ruta_archivo)
 
# Ejemplo de uso
copia_seguridad_directorio(os.getcwd(), "copia_seguridad.zip")
print("Copia de seguridad del directorio completa.")

Esta función copia_seguridad_directorio() recibe como entrada una ruta de directorio y un nombre de archivo ZIP, y crea un archivo ZIP de todos los archivos en el directorio y sus subdirectorios.

Herramientas de organización y limpieza de archivos

Puedes utilizar las técnicas de listado y filtrado de archivos para crear scripts que organicen o limpien archivos en un directorio. Por ejemplo, puedes ordenar los archivos en subdirectorios según su extensión de archivo.

import os
import shutil
 
def organizar_archivos(directorio):
    """
    Organiza archivos en un directorio moviéndolos a subdirectorios según su extensión de archivo.
    """
    for archivo in os.listdir(directorio):
        ruta_archivo = os.path.join(directorio, archivo)
        if os.path.isfile(ruta_archivo):
            extension = os.path.splitext(archivo)[1]
            destino = os.path.join(directorio, extension.lstrip("."))
            try:
                os.makedirs(destino)
            except FileExistsError:
                pass
            shutil.move(ruta_archivo, destino)
 
# Ejemplo de uso
organizar_archivos(os.getcwd())
print("Archivos organizados correctamente.")

Esta función organizar_archivos() toma como entrada un directorio y organiza los archivos moviéndolos a subdirectorios según su extensión de archivo. Aquí hay un ejemplo de una función simple que calcula el área de un rectángulo:

def calcular_area(longitud, ancho):
    area = longitud * ancho
    return area
 
# Uso
longitud_rectángulo = 5
ancho_rectángulo = 3
resultado = calcular_area(longitud_rectángulo, ancho_rectángulo)
print(f"El área del rectángulo es {resultado} unidades cuadradas.")

En este ejemplo, la función calcular_area() toma dos parámetros, longitud y ancho, y calcula el área multiplicándolos. La función luego devuelve el área calculada.

También puedes definir funciones que no toman ningún parámetro y no devuelven ningún valor:

def saludar_usuario():
    print("¡Hola, usuario!")
 
# Uso
saludar_usuario()

Las funciones también pueden tener valores predeterminados para los parámetros, lo que las hace más flexibles:

def calcular_area_circulo(radio, pi=3.14159):
    area = pi * radio ** 2
    return area
 
# Uso
radio_circulo = 4
resultado = calcular_area_circulo(radio_circulo)
print(f"El área del círculo es {resultado} unidades cuadradas.")
 
# Uso con valor personalizado de pi
resultado = calcular_area_circulo(radio_circulo, pi=3.14)
print(f"El área del círculo es {resultado} unidades cuadradas.")

En este ejemplo, la función calcular_area_circulo() tiene un valor predeterminado de 3.14159 para el parámetro pi, pero también puedes pasar un valor personalizado si es necesario.

Módulos y Paquetes

El diseño modular de Python te permite organizar tu código en componentes reutilizables llamados módulos. Los módulos son archivos de Python que contienen funciones, clases y variables. Puedes importar módulos y utilizar la funcionalidad que proporcionan en tu propio código.

Aquí tienes un ejemplo de cómo utilizar el módulo integrado math:

import math
 
# Uso
radio = 5
area_circulo = math.pi * radio ** 2
print(f"El área del círculo es {area_circulo:.2f} unidades cuadradas.")

En este ejemplo, importamos el módulo math y utilizamos su constante pi para calcular el área de un círculo.

También puedes importar funciones o variables específicas de un módulo:

from math import pi, sqrt
 
# Uso
radio = 5
area_circulo = pi * radio ** 2
raiz_cuadrada = sqrt(25)
print(f"El área del círculo es {area_circulo:.2f} unidades cuadradas.")
print(f"La raíz cuadrada de 25 es {raiz_cuadrada}.")

Este enfoque te permite acceder directamente a las funciones pi y sqrt(), sin tener que escribir el nombre completo del módulo math. antes.

Python también admite la creación de paquetes, que son colecciones de módulos relacionados. Los paquetes te ayudan a organizar tu código en una estructura jerárquica, facilitando la gestión y distribución de tu software.

Aquí tienes un ejemplo de cómo crear un paquete simple:

mi_paquete/
    __init__.py
    math_utils.py
    string_utils.py

En este ejemplo, mi_paquete es el paquete, y math_utils.py y string_utils.py son los módulos dentro del paquete. El archivo __init__.py es necesario para marcar el directorio como un paquete.

Luego puedes importar y utilizar las funciones de los módulos dentro del paquete:

from mi_paquete.math_utils import calcular_area
from mi_paquete.string_utils import revertir_cadena
 
# Uso
area_rectángulo = calcular_area(5, 3)
print(f"El área del rectángulo es {area_rectángulo} unidades cuadradas.")
 
cadena_invertida = revertir_cadena("Python")
print(f"La cadena invertida es: {cadena_invertida}")

Organizar tu código en módulos y paquetes lo hace más mantenible, reutilizable y más fácil de distribuir.

Manejo de Excepciones

En Python, las excepciones son eventos que ocurren durante la ejecución de un programa y que interrumpen el flujo normal de las instrucciones del programa. El manejo de excepciones es un aspecto importante para escribir código robusto y confiable.

Aquí tienes un ejemplo de cómo manejar una excepción ZeroDivisionError:

def dividir_numeros(a, b):
    try:
        resultado = a / b
        return resultado
    except ZeroDivisionError:
        print("Error: División por cero.")
        return None
 
# Uso
dividendo = 10
divisor = 0
resultado = dividir_numeros(dividendo, divisor)
if resultado is not None:
    print(f"El resultado de {dividendo} / {divisor} es {resultado}.")
else:
    print("No se puede realizar la división.")

En este ejemplo, la función dividir_numeros() intenta dividir el parámetro a por el parámetro b. Si b es cero, se genera una excepción ZeroDivisionError, y la función la maneja imprimiendo un mensaje de error y devolviendo None.

También puedes manejar múltiples excepciones en un solo bloque try-except:

def procesar_entrada(entrada_usuario):
    try:
        valor = int(entrada_usuario)
        return valor
    except ValueError:
        print("Error: Entrada no válida. Por favor ingresa un número.")
        return None
    except Exception as e:
        print(f"Ocurrió un error inesperado: {e}")
        return None
 
# Uso
entrada_usuario = input("Ingresa un número: ")
resultado = procesar_entrada(entrada_usuario)
if resultado is not None:
    print(f"El valor ingresado es: {resultado}")

En este ejemplo, la función procesar_entrada() primero intenta convertir entrada_usuario a un entero usando la función int(). Si la entrada no es un número válido, se genera una excepción ValueError, que se maneja imprimiendo un mensaje de error y devolviendo None. Además, la función también maneja cualquier otra excepción inesperada imprimiendo un mensaje de error genérico y devolviendo None.

El manejo de excepciones es crucial para crear aplicaciones sólidas y fáciles de usar que puedan manejar con elegancia situaciones inesperadas.

Entrada/Salida de Archivos

Python proporciona funciones y métodos incorporados para leer y escribir en archivos. Esto te permite persistir datos e interactuar con el sistema de archivos.

Aquí tienes un ejemplo de cómo leer desde un archivo:

# Leyendo desde un archivo
with open("ejemplo.txt", "r") as archivo:
    contenido = archivo.read()
    print(f"Contenido del archivo:\n{contenido}")

En este ejemplo, se utiliza la función open() para abrir el archivo "example.txt" en modo lectura ("r"). La declaración with asegura que el archivo se cierre correctamente después de que se ejecute el bloque de código, incluso si ocurre una excepción.

También puedes leer el archivo línea por línea:

# Leyendo el archivo línea por línea
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

Este ejemplo lee el archivo línea por línea e imprime cada línea después de eliminar los espacios en blanco iniciales o finales utilizando el método strip().

Para escribir en un archivo, puedes utilizar el modo de escritura ("w") o el modo de apendizaje ("a"):

# Escribiendo en un archivo
with open("output.txt", "w") as file:
    file.write("Esta es la primera línea.\n")
    file.write("Esta es la segunda línea.\n")
 
# Apendizando a un archivo
with open("output.txt", "a") as file:
    file.write("Esta es una nueva línea añadida al archivo.\n")

En el primer ejemplo, el archivo "output.txt" se abre en modo de escritura y se escriben dos líneas de texto. En el segundo ejemplo, el mismo archivo se abre en modo de apendizaje y se agrega una nueva línea al final del archivo.

Las operaciones de E/S de archivos son esenciales para tareas como leer archivos de configuración, registrar datos y guardar/cargar el estado de la aplicación.

Conclusión

En este tutorial, has aprendido sobre varios conceptos intermedios de Python, incluyendo funciones, módulos y paquetes, manejo de excepciones y E/S de archivos. Estos temas son fundamentales para construir aplicaciones Python más complejas y robustas.

Al comprender las funciones, puedes crear código reutilizable y modular que se puede mantener y ampliar fácilmente. Los módulos y paquetes te ayudan a organizar tu código, haciéndolo más manejable y compartible. El manejo de excepciones es crucial para escribir software confiable que pueda manejar situaciones inesperadas correctamente. Por último, las operaciones de E/S de archivos te permiten persistir y interactuar con datos, lo cual es esencial para muchas aplicaciones del mundo real.

A medida que sigas explorando y practicando Python, recuerda experimentar con estos conceptos, probar diferentes casos de uso y expandir continuamente tus conocimientos. La versatilidad de Python y su extenso ecosistema de bibliotecas y frameworks lo convierten en un lenguaje poderoso para una amplia gama de aplicaciones, desde el desarrollo web hasta el análisis de datos y más allá.

MoeNagy Dev