Python

Python

Tutorial Python: Módulo sys

Aprende a usar el módulo sys en Python para manejar argumentos, rutas de importación y controlar la salida del programa de forma profesional.

Aprende Python y certifícate

Argumentos de línea de comandos

El módulo sys de Python proporciona acceso a variables y funciones que interactúan directamente con el intérprete. Una de sus funcionalidades más útiles es el acceso a los argumentos de línea de comandos a través de sys.argv, que permite que nuestros programas reciban información cuando son ejecutados desde la terminal.

Cuando ejecutamos un script de Python desde la línea de comandos, podemos pasarle parámetros adicionales que el programa puede utilizar para modificar su comportamiento. Estos parámetros se capturan en una lista llamada sys.argv.

Estructura básica de sys.argv

Para empezar a trabajar con argumentos de línea de comandos, primero necesitamos importar el módulo sys:

import sys

La lista sys.argv siempre contiene al menos un elemento: el nombre del script que se está ejecutando. Los argumentos adicionales se añaden a continuación:

# archivo: mostrar_args.py
import sys

print(f"Nombre del script: {sys.argv[0]}")
print(f"Número de argumentos: {len(sys.argv) - 1}")
print(f"Argumentos: {sys.argv[1:]}")

Si ejecutamos este script con argumentos adicionales:

python mostrar_args.py uno dos tres

Obtendremos una salida similar a:

Nombre del script: mostrar_args.py
Número de argumentos: 3
Argumentos: ['uno', 'dos', 'tres']

Procesamiento básico de argumentos

Los argumentos en sys.argv siempre se reciben como cadenas de texto, independientemente de su contenido. Si necesitamos trabajar con números u otros tipos de datos, debemos realizar la conversión manualmente:

# archivo: calculadora.py
import sys

if len(sys.argv) != 4:
    print("Uso: python calculadora.py <número1> <operación> <número2>")
    sys.exit(1)

try:
    num1 = float(sys.argv[1])
    operacion = sys.argv[2]
    num2 = float(sys.argv[3])
    
    if operacion == "+":
        resultado = num1 + num2
    elif operacion == "-":
        resultado = num1 - num2
    elif operacion == "*":
        resultado = num1 * num2
    elif operacion == "/":
        if num2 == 0:
            print("Error: División por cero")
            sys.exit(1)
        resultado = num1 / num2
    else:
        print(f"Operación no soportada: {operacion}")
        sys.exit(1)
        
    print(f"Resultado: {resultado}")
    
except ValueError:
    print("Error: Los argumentos deben ser números válidos")
    sys.exit(1)

Este script implementa una calculadora simple que acepta dos números y una operación. Podemos usarlo así:

python calculadora.py 5 + 3

Y obtendremos:

Resultado: 8.0

Patrones comunes para argumentos

Existen varios patrones comunes para trabajar con argumentos de línea de comandos:

  • Argumentos posicionales: El orden de los argumentos determina su significado.
  • Argumentos con banderas: Utilizan prefijos como - o -- para identificar opciones.
  • Argumentos con valores: Una bandera seguida de un valor (por ejemplo, --output archivo.txt).

Veamos un ejemplo que combina estos patrones:

# archivo: procesador.py
import sys

def mostrar_ayuda():
    print("Uso: python procesador.py [opciones] archivo")
    print("Opciones:")
    print("  -h, --help     Muestra esta ayuda")
    print("  -v, --verbose  Muestra información detallada")
    print("  -o ARCHIVO     Especifica archivo de salida")
    sys.exit(0)

# Valores predeterminados
verbose = False
archivo_salida = None
archivos_entrada = []

# Procesar argumentos
i = 1
while i < len(sys.argv):
    arg = sys.argv[i]
    
    if arg in ("-h", "--help"):
        mostrar_ayuda()
    elif arg in ("-v", "--verbose"):
        verbose = True
    elif arg == "-o" and i + 1 < len(sys.argv):
        archivo_salida = sys.argv[i + 1]
        i += 1  # Saltar el siguiente argumento
    elif arg.startswith("-"):
        print(f"Opción desconocida: {arg}")
        sys.exit(1)
    else:
        # No es una opción, debe ser un archivo de entrada
        archivos_entrada.append(arg)
    
    i += 1

# Verificar que se proporcionó al menos un archivo de entrada
if not archivos_entrada:
    print("Error: Debe especificar al menos un archivo de entrada")
    mostrar_ayuda()

# Mostrar configuración
if verbose:
    print("Configuración:")
    print(f"  Modo detallado: Activado")
    print(f"  Archivo de salida: {archivo_salida or 'Salida estándar'}")
    print(f"  Archivos de entrada: {', '.join(archivos_entrada)}")

# Aquí iría el código para procesar los archivos
print(f"Procesando {len(archivos_entrada)} archivo(s)...")

Este script puede usarse de varias formas:

python procesador.py -v -o resultado.txt datos.csv
python procesador.py --help
python procesador.py archivo1.txt archivo2.txt

Uso de argparse para argumentos más complejos

Aunque sys.argv es útil para casos simples, Python incluye el módulo argparse en su biblioteca estándar para manejar argumentos de forma más robusta. Este módulo simplifica la validación, documentación y procesamiento de argumentos complejos:

# archivo: conversor.py
import sys
import argparse

def main():
    # Crear el analizador de argumentos
    parser = argparse.ArgumentParser(
        description="Convierte temperaturas entre Celsius y Fahrenheit"
    )
    
    # Añadir argumentos
    parser.add_argument(
        "temperatura", 
        type=float,
        help="Valor de temperatura a convertir"
    )
    
    parser.add_argument(
        "-f", "--fahrenheit",
        action="store_true",
        help="Convertir de Fahrenheit a Celsius (por defecto: Celsius a Fahrenheit)"
    )
    
    parser.add_argument(
        "-p", "--precision",
        type=int,
        default=2,
        help="Número de decimales en el resultado (por defecto: 2)"
    )
    
    # Analizar los argumentos
    args = parser.parse_args()
    
    # Realizar la conversión
    if args.fahrenheit:
        # Convertir de Fahrenheit a Celsius
        resultado = (args.temperatura - 32) * 5/9
        origen = "Fahrenheit"
        destino = "Celsius"
    else:
        # Convertir de Celsius a Fahrenheit
        resultado = (args.temperatura * 9/5) + 32
        origen = "Celsius"
        destino = "Fahrenheit"
    
    # Mostrar el resultado con la precisión especificada
    print(f"{args.temperatura}° {origen} = {resultado:.{args.precision}f}° {destino}")

if __name__ == "__main__":
    main()

Este conversor de temperaturas puede usarse de varias formas:

python conversor.py 25        # Convierte 25°C a Fahrenheit
python conversor.py -f 98.6   # Convierte 98.6°F a Celsius
python conversor.py 100 -p 4  # Muestra el resultado con 4 decimales

Consejos prácticos para trabajar con argumentos

  • Validación temprana: Verifica que los argumentos sean válidos al inicio del programa.
  • Mensajes de error claros: Proporciona mensajes de error descriptivos cuando faltan argumentos o tienen formato incorrecto.
  • Documentación integrada: Incluye ayuda sobre cómo usar tu programa con la opción -h o --help.
  • Valores predeterminados: Define comportamientos predeterminados razonables cuando no se proporcionan ciertos argumentos.
  • Códigos de salida: Utiliza sys.exit(0) para una salida exitosa y sys.exit(1) (u otro número distinto de cero) para indicar errores.

Ejemplo práctico: Procesador de archivos

Veamos un ejemplo más completo que procesa archivos de texto:

# archivo: contador_palabras.py
import sys
import os

def contar_palabras(archivo):
    """Cuenta las palabras en un archivo de texto."""
    try:
        with open(archivo, 'r', encoding='utf-8') as f:
            contenido = f.read()
            palabras = contenido.split()
            return len(palabras)
    except FileNotFoundError:
        print(f"Error: No se encontró el archivo '{archivo}'")
        return None
    except Exception as e:
        print(f"Error al procesar '{archivo}': {e}")
        return None

def main():
    # Verificar argumentos
    if len(sys.argv) < 2:
        print("Uso: python contador_palabras.py <archivo1> [archivo2 ...]")
        sys.exit(1)
    
    archivos = sys.argv[1:]
    total_palabras = 0
    archivos_procesados = 0
    
    # Procesar cada archivo
    for archivo in archivos:
        if not os.path.exists(archivo):
            print(f"Advertencia: El archivo '{archivo}' no existe")
            continue
            
        if os.path.isdir(archivo):
            print(f"Advertencia: '{archivo}' es un directorio, no un archivo")
            continue
            
        palabras = contar_palabras(archivo)
        if palabras is not None:
            print(f"{archivo}: {palabras} palabras")
            total_palabras += palabras
            archivos_procesados += 1
    
    # Mostrar resumen
    if archivos_procesados > 0:
        print(f"\nResumen: {total_palabras} palabras en {archivos_procesados} archivo(s)")
        print(f"Promedio: {total_palabras / archivos_procesados:.1f} palabras por archivo")
    else:
        print("\nNo se procesó ningún archivo correctamente")
        sys.exit(1)

if __name__ == "__main__":
    main()

Este script cuenta las palabras en uno o más archivos de texto y muestra estadísticas:

python contador_palabras.py README.md docs/manual.txt notas.txt

La salida podría ser:

README.md: 245 palabras
docs/manual.txt: 1203 palabras
Advertencia: El archivo 'notas.txt' no existe

Resumen: 1448 palabras en 2 archivo(s)
Promedio: 724.0 palabras por archivo

Variables y funciones del sistema

El módulo sys proporciona acceso a variables y funciones que interactúan directamente con el intérprete de Python y el sistema operativo subyacente. Estas herramientas nos permiten obtener información sobre el entorno de ejecución y modificar ciertos aspectos del comportamiento del intérprete.

Para utilizar estas funcionalidades, primero debemos importar el módulo:

import sys

Información sobre la versión de Python

El módulo sys nos permite acceder a información detallada sobre la versión de Python que estamos utilizando:

import sys

# Versión de Python como cadena de texto
print(f"Versión de Python: {sys.version}")

# Información de versión como tupla (major, minor, micro, nivel, serial)
print(f"Versión como tupla: {sys.version_info}")

# Acceso a componentes individuales de la versión
print(f"Versión principal: {sys.version_info.major}")
print(f"Versión secundaria: {sys.version_info.minor}")

Esta información es útil para escribir código compatible con diferentes versiones de Python o para verificar requisitos mínimos:

import sys

# Verificar si estamos usando Python 3.8 o superior
if sys.version_info >= (3, 8):
    print("Características de Python 3.8+ disponibles")
else:
    print("Se requiere Python 3.8 o superior")
    sys.exit(1)

Plataforma y entorno de ejecución

El módulo sys también proporciona información sobre la plataforma en la que se está ejecutando Python:

import sys

# Sistema operativo (posix, nt, java)
print(f"Plataforma: {sys.platform}")

# Tamaño de palabra del sistema (32 o 64 bits)
print(f"Tamaño de palabra: {sys.maxsize.bit_length() + 1} bits")

# Codificación predeterminada para archivos
print(f"Codificación predeterminada: {sys.getdefaultencoding()}")

Estas variables son útiles para escribir código que se comporte de manera diferente según la plataforma:

import sys

# Detectar el sistema operativo
if sys.platform.startswith('win'):
    config_path = 'C:\\config.ini'
    print("Sistema Windows detectado")
elif sys.platform.startswith('darwin'):
    config_path = '/Users/usuario/config.ini'
    print("Sistema macOS detectado")
else:
    config_path = '/etc/app/config.ini'
    print("Sistema Unix/Linux detectado")

Entrada y salida estándar

El módulo sys proporciona acceso a los flujos estándar de entrada, salida y error:

  • sys.stdin: Flujo de entrada estándar
  • sys.stdout: Flujo de salida estándar
  • sys.stderr: Flujo de error estándar

Estos objetos son archivos especiales que podemos usar para leer la entrada del usuario o escribir salida:

import sys

# Leer una línea de la entrada estándar
print("Ingrese su nombre:")
nombre = sys.stdin.readline().strip()

# Escribir en la salida estándar
sys.stdout.write(f"Hola, {nombre}!\n")

# Escribir en el flujo de error
sys.stderr.write("Este es un mensaje de error\n")

Una aplicación común es redirigir temporalmente la salida estándar a un archivo:

import sys

# Guardar la referencia original a stdout
stdout_original = sys.stdout

try:
    # Redirigir stdout a un archivo
    with open('salida.log', 'w') as archivo:
        sys.stdout = archivo
        print("Este texto se escribe en el archivo")
        print("También este texto")
finally:
    # Restaurar stdout a su valor original
    sys.stdout = stdout_original

print("Este texto se muestra en la consola")

Control de memoria y recursos

El módulo sys proporciona funciones para gestionar la memoria y otros recursos del sistema:

import sys

# Tamaño de un objeto en bytes
size = sys.getsizeof([1, 2, 3, 4, 5])
print(f"Tamaño de la lista: {size} bytes")

# Obtener el conteo de referencias de un objeto
lista = [1, 2, 3]
otra_referencia = lista
print(f"Referencias a la lista: {sys.getrefcount(lista) - 1}")  # Restamos 1 por la referencia temporal en getrefcount

También podemos controlar el recolector de basura de Python:

import sys
import gc

# Desactivar el recolector de basura automático
gc.disable()

# Realizar operaciones intensivas...
datos = [list(range(1000)) for _ in range(100)]

# Forzar una recolección de basura manual
n = gc.collect()
print(f"Se liberaron {n} objetos")

# Reactivar el recolector de basura
gc.enable()

Variables de configuración del intérprete

El módulo sys permite acceder y modificar varias configuraciones del intérprete:

import sys

# Límite de recursión actual
print(f"Límite de recursión: {sys.getrecursionlimit()}")

# Aumentar el límite de recursión
sys.setrecursionlimit(3000)
print(f"Nuevo límite: {sys.getrecursionlimit()}")

# Obtener el tamaño máximo de cadena mostrada en la representación de objetos
print(f"Límite de visualización: {sys.getsizeof('x' * 100)}")

Un uso común es modificar el límite de recursión para algoritmos que requieren muchas llamadas recursivas:

import sys

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

# Aumentar el límite para cálculos recursivos profundos
sys.setrecursionlimit(3000)

try:
    resultado = factorial(1000)
    print(f"Factorial calculado correctamente")
except RecursionError:
    print("La recursión fue demasiado profunda")

Módulos cargados y rutas de búsqueda

Podemos examinar qué módulos están actualmente cargados y dónde Python busca módulos:

import sys
import math
import random

# Ver todos los módulos cargados
print("Módulos cargados:")
for nombre, modulo in sys.modules.items():
    if nombre in ['math', 'random', 'sys']:
        print(f"  - {nombre}: {modulo}")

# Verificar si un módulo está cargado
if 'numpy' in sys.modules:
    print("NumPy está cargado")
else:
    print("NumPy no está cargado")

Funciones de finalización y hooks

El módulo sys proporciona mecanismos para registrar funciones de finalización que se ejecutarán cuando el programa termine:

import sys
import atexit

def limpiar_recursos():
    print("Limpiando recursos...")
    # Aquí iría el código para cerrar archivos, conexiones, etc.

# Registrar función para ejecutarse al salir
atexit.register(limpiar_recursos)

# También podemos registrar funciones para ejecutarse cuando ocurran excepciones no capturadas
def manejar_excepcion(tipo, valor, traceback):
    print(f"Error no capturado: {valor}")
    # Registrar el error, notificar, etc.
    sys.__excepthook__(tipo, valor, traceback)  # Llamar al manejador original

# Reemplazar el manejador de excepciones predeterminado
sys.excepthook = manejar_excepcion

# Simular un error
print("Programa en ejecución...")
# Descomentar para probar: 1/0  # Esto generará una excepción ZeroDivisionError

Monitoreo de uso de memoria

Podemos usar sys para monitorear el uso de memoria de nuestras aplicaciones:

import sys

def mostrar_uso_memoria(descripcion):
    # Obtener información sobre objetos en memoria
    objetos = {}
    for modulo in sys.modules.values():
        for nombre in dir(modulo):
            obj = getattr(modulo, nombre)
            objetos[id(obj)] = obj
    
    # Contar tipos de objetos
    tipos = {}
    for obj in objetos.values():
        tipo = type(obj).__name__
        tipos[tipo] = tipos.get(tipo, 0) + 1
    
    # Mostrar los 5 tipos más comunes
    print(f"\nUso de memoria ({descripcion}):")
    for tipo, cantidad in sorted(tipos.items(), key=lambda x: x[1], reverse=True)[:5]:
        print(f"  - {tipo}: {cantidad} instancias")

# Monitorear antes y después de una operación intensiva
mostrar_uso_memoria("Inicial")

# Crear muchos objetos
grandes_listas = [list(range(10000)) for _ in range(10)]

mostrar_uso_memoria("Después de crear listas")

# Liberar memoria
grandes_listas = None

mostrar_uso_memoria("Después de liberar")

Ejemplo práctico: Monitor de recursos

Veamos un ejemplo más completo que monitorea el uso de recursos de un programa:

import sys
import time
import os
import psutil  # Requiere: pip install psutil

def monitor_recursos(intervalo=1.0, duracion=10):
    """Monitorea el uso de recursos del proceso actual."""
    proceso = psutil.Process(os.getpid())
    
    print(f"Monitoreando recursos del proceso {os.getpid()}:")
    print(f"Python {sys.version.split()[0]} en {sys.platform}")
    print(f"{'Tiempo (s)':<10} {'CPU %':<8} {'Memoria (MB)':<12} {'Objetos':<10}")
    print("-" * 42)
    
    inicio = time.time()
    while time.time() - inicio < duracion:
        # Obtener uso de CPU y memoria
        cpu_percent = proceso.cpu_percent()
        memoria = proceso.memory_info().rss / (1024 * 1024)  # Convertir a MB
        
        # Contar objetos (simplificado)
        objetos = len(gc.get_objects())
        
        # Mostrar estadísticas
        tiempo_transcurrido = time.time() - inicio
        print(f"{tiempo_transcurrido:<10.1f} {cpu_percent:<8.1f} {memoria:<12.2f} {objetos:<10}")
        
        time.sleep(intervalo)

# Ejemplo de uso
if __name__ == "__main__":
    import gc
    
    # Crear algunos datos para ver el efecto
    datos = []
    
    # Iniciar monitoreo
    monitor_recursos(intervalo=0.5, duracion=3)
    
    # Crear más datos y ver el efecto
    for i in range(5):
        datos.append([0] * 1000000)  # Crear una lista grande
        print(f"Creada lista grande #{i+1}")
        monitor_recursos(intervalo=0.5, duracion=1)
    
    # Liberar memoria
    datos = None
    gc.collect()
    print("Memoria liberada")
    monitor_recursos(intervalo=0.5, duracion=2)

Este script muestra cómo podemos usar sys junto con otras bibliotecas para monitorear el comportamiento de nuestras aplicaciones y detectar problemas como fugas de memoria o uso excesivo de CPU.

Manejo de rutas de importación

El módulo sys proporciona herramientas fundamentales para gestionar las rutas de importación en Python, permitiéndonos controlar dónde y cómo el intérprete busca los módulos que intentamos importar. Entender este mecanismo es esencial para desarrollar aplicaciones modulares y mantener una estructura de proyecto organizada.

Cuando importamos un módulo en Python, el intérprete busca en una lista ordenada de directorios para encontrarlo. Esta lista se almacena en la variable sys.path, que podemos examinar y modificar durante la ejecución del programa.

Explorando sys.path

Para entender cómo Python encuentra los módulos, podemos examinar el contenido de sys.path:

import sys

# Mostrar todas las rutas de búsqueda
for i, ruta in enumerate(sys.path):
    print(f"{i}: {ruta}")

Al ejecutar este código, veremos una lista de directorios que típicamente incluye:

  1. El directorio del script que se está ejecutando (o directorio actual si estamos en modo interactivo)
  2. Los directorios especificados en la variable de entorno PYTHONPATH
  3. Directorios de instalación estándar de Python (bibliotecas del sistema)
  4. Directorios de paquetes instalados (como los instalados con pip)

Modificando las rutas de importación

Podemos modificar dinámicamente sys.path para incluir directorios adicionales donde Python buscará módulos:

import sys
import os

# Añadir un directorio al inicio de sys.path
directorio_modulos = os.path.join(os.path.dirname(__file__), "modulos")
sys.path.insert(0, directorio_modulos)

# Ahora podemos importar módulos desde ese directorio
import mi_modulo_personalizado

Las operaciones más comunes para modificar sys.path son:

  • sys.path.append(ruta): Añade una ruta al final de la lista
  • sys.path.insert(0, ruta): Añade una ruta al principio de la lista (mayor prioridad)
  • sys.path.remove(ruta): Elimina una ruta de la lista

Patrones de uso comunes

1. Importar módulos desde directorios hermanos

Un problema común es importar módulos que están en directorios adyacentes. Por ejemplo, con esta estructura:

proyecto/
├── modulo_a/
│   └── script_a.py
└── modulo_b/
    └── script_b.py

Si queremos importar script_b.py desde script_a.py, podemos hacer:

# En script_a.py
import sys
import os

# Obtener la ruta al directorio raíz del proyecto
directorio_raiz = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, directorio_raiz)

# Ahora podemos importar usando rutas relativas al directorio raíz
from modulo_b import script_b

2. Crear un entorno de pruebas aislado

Podemos manipular sys.path para crear un entorno de pruebas que use versiones específicas de módulos:

import sys
import os

# Guardar el path original
path_original = sys.path.copy()

# Configurar un entorno aislado para pruebas
def configurar_entorno_pruebas():
    # Limpiar sys.path y añadir solo lo necesario
    sys.path = [os.path.abspath("./modulos_prueba")]
    sys.path.append(os.path.abspath("./mocks"))
    
    # Ahora las importaciones usarán nuestras versiones de prueba
    
def restaurar_entorno():
    # Restaurar sys.path a su estado original
    sys.path = path_original

# Ejemplo de uso
try:
    configurar_entorno_pruebas()
    import modulo_a  # Usará la versión de prueba
    # Ejecutar pruebas...
finally:
    restaurar_entorno()

3. Importación condicional basada en disponibilidad

Podemos usar sys.path junto con manejo de excepciones para implementar importaciones alternativas:

import sys
import os

try:
    # Intentar importar un módulo
    import biblioteca_rapida
except ImportError:
    # Si no está disponible, añadir ruta a nuestra implementación alternativa
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), "alternativas"))
    import biblioteca_alternativa as biblioteca_rapida
    print("Usando implementación alternativa")

Herramientas para trabajar con rutas de importación

Verificar si un módulo puede ser importado

Podemos verificar si un módulo está disponible en las rutas de importación sin intentar importarlo directamente:

import sys
import importlib.util

def modulo_disponible(nombre_modulo):
    """Verifica si un módulo puede ser importado sin importarlo realmente."""
    spec = importlib.util.find_spec(nombre_modulo)
    return spec is not None

# Ejemplo de uso
if modulo_disponible("numpy"):
    print("NumPy está disponible para importar")
else:
    print("NumPy no está disponible")

Encontrar la ruta de un módulo importado

Podemos determinar desde qué archivo se importó un módulo específico:

import sys
import os
import importlib.util

def encontrar_ruta_modulo(nombre_modulo):
    """Encuentra la ruta del archivo de un módulo sin importarlo."""
    spec = importlib.util.find_spec(nombre_modulo)
    if spec is None:
        return None
    return spec.origin

# Ejemplo de uso
ruta_os = encontrar_ruta_modulo("os")
print(f"El módulo 'os' se encuentra en: {ruta_os}")

Aplicaciones prácticas

Crear un cargador de plugins

Podemos usar sys.path para implementar un sistema de plugins que busque módulos en múltiples directorios:

import sys
import os
import importlib

class CargadorPlugins:
    def __init__(self):
        self.plugins = {}
        self.directorios_plugins = []
    
    def agregar_directorio(self, directorio):
        """Añade un directorio a la búsqueda de plugins."""
        ruta_abs = os.path.abspath(directorio)
        if os.path.isdir(ruta_abs) and ruta_abs not in self.directorios_plugins:
            self.directorios_plugins.append(ruta_abs)
    
    def descubrir_plugins(self):
        """Busca plugins en todos los directorios registrados."""
        # Guardar el path original
        path_original = sys.path.copy()
        
        try:
            for directorio in self.directorios_plugins:
                # Añadir temporalmente el directorio al path
                if directorio not in sys.path:
                    sys.path.insert(0, directorio)
                
                # Buscar archivos Python en el directorio
                for archivo in os.listdir(directorio):
                    if archivo.endswith('.py') and not archivo.startswith('_'):
                        nombre_modulo = archivo[:-3]  # Quitar la extensión .py
                        try:
                            # Importar el módulo dinámicamente
                            modulo = importlib.import_module(nombre_modulo)
                            
                            # Verificar si es un plugin válido (tiene función 'ejecutar')
                            if hasattr(modulo, 'ejecutar'):
                                self.plugins[nombre_modulo] = modulo
                                print(f"Plugin cargado: {nombre_modulo}")
                        except ImportError as e:
                            print(f"Error al cargar plugin {nombre_modulo}: {e}")
        finally:
            # Restaurar el path original
            sys.path = path_original
    
    def ejecutar_plugin(self, nombre, *args, **kwargs):
        """Ejecuta un plugin específico."""
        if nombre in self.plugins:
            return self.plugins[nombre].ejecutar(*args, **kwargs)
        else:
            raise ValueError(f"Plugin no encontrado: {nombre}")

# Ejemplo de uso
if __name__ == "__main__":
    cargador = CargadorPlugins()
    cargador.agregar_directorio("./plugins")
    cargador.agregar_directorio("./plugins_externos")
    
    cargador.descubrir_plugins()
    
    # Ejecutar un plugin si está disponible
    if "conversor_texto" in cargador.plugins:
        resultado = cargador.ejecutar_plugin("conversor_texto", 
                                            texto="Hola Mundo", 
                                            mayusculas=True)
        print(f"Resultado: {resultado}")

Implementar un importador personalizado

Para casos avanzados, podemos crear un importador personalizado que modifique cómo Python busca y carga módulos:

import sys
import importlib.abc
import importlib.machinery

class ImportadorComprimido(importlib.abc.MetaPathFinder):
    """Importador personalizado que puede cargar módulos desde archivos ZIP."""
    
    def __init__(self, archivo_zip):
        self.archivo_zip = archivo_zip
        # Aquí iría la lógica para acceder al contenido del ZIP
        
    def find_spec(self, fullname, path, target=None):
        # Verificar si el módulo está en nuestro archivo ZIP
        if self._tiene_modulo(fullname):
            # Crear y devolver un spec para el módulo
            return importlib.machinery.ModuleSpec(
                name=fullname,
                loader=self._crear_loader(fullname),
                origin=f"zip:{self.archivo_zip}:/{fullname.replace('.', '/')}.py"
            )
        return None
    
    def _tiene_modulo(self, nombre):
        # Verificar si el módulo existe en el ZIP
        # (Implementación simplificada)
        return True
    
    def _crear_loader(self, nombre):
        # Crear un loader para el módulo
        # (Implementación simplificada)
        return importlib.abc.Loader()

# Registrar el importador personalizado
sys.meta_path.insert(0, ImportadorComprimido("modulos.zip"))

# Ahora podemos importar módulos desde el archivo ZIP
try:
    import modulo_comprimido
    print("Módulo importado correctamente desde ZIP")
except ImportError as e:
    print(f"Error al importar: {e}")

Mejores prácticas

Al trabajar con rutas de importación, es recomendable seguir estas prácticas:

  • Evita modificar sys.path en código de producción cuando sea posible. En su lugar, utiliza paquetes correctamente estructurados.
  • Usa modificaciones temporales de sys.path con bloques try/finally para restaurar el estado original.
  • Prefiere rutas absolutas sobre rutas relativas al modificar sys.path para evitar problemas con el directorio de trabajo.
  • Documenta claramente cualquier modificación de sys.path para facilitar el mantenimiento.
  • Considera alternativas como PYTHONPATH o archivos .pth para configuraciones permanentes.
# Ejemplo de modificación temporal y segura de sys.path
import sys
import os
import contextlib

@contextlib.contextmanager
def ruta_temporal(directorio):
    """Añade temporalmente un directorio a sys.path y lo restaura después."""
    ruta_original = sys.path.copy()
    try:
        sys.path.insert(0, os.path.abspath(directorio))
        yield
    finally:
        sys.path = ruta_original

# Uso con administrador de contexto
with ruta_temporal("./lib_externa"):
    import modulo_especial
    resultado = modulo_especial.procesar_datos()

# Aquí sys.path ya está restaurado

El manejo adecuado de las rutas de importación es una habilidad fundamental para desarrollar aplicaciones Python modulares y mantenibles, especialmente en proyectos grandes o cuando se trabaja con dependencias complejas.

Salida del programa

El módulo sys proporciona varias funcionalidades para controlar la salida del programa en Python, permitiéndonos gestionar cómo y cuándo nuestro programa finaliza su ejecución. Estas herramientas son fundamentales para desarrollar aplicaciones robustas que puedan comunicar correctamente su estado de finalización al sistema operativo.

Terminación controlada con sys.exit()

La función sys.exit() es la forma recomendada para terminar la ejecución de un programa Python de manera controlada:

import sys

def procesar_archivo(ruta):
    try:
        with open(ruta, 'r') as archivo:
            contenido = archivo.read()
            return contenido
    except FileNotFoundError:
        print(f"Error: No se encontró el archivo '{ruta}'")
        sys.exit(1)  # Terminar con código de error

# Ejemplo de uso
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Uso: python script.py <archivo>")
        sys.exit(1)  # Terminar con código de error
        
    datos = procesar_archivo(sys.argv[1])
    print("Procesamiento completado con éxito")
    sys.exit(0)  # Terminar con éxito

La función sys.exit() acepta un argumento opcional que representa el código de salida:

  • sys.exit(0): Indica una terminación exitosa (valor predeterminado si no se especifica)
  • sys.exit(1) o cualquier número distinto de cero: Indica una terminación con error

Estos códigos de salida son importantes cuando nuestros scripts son utilizados por otros programas o en scripts de shell, ya que permiten determinar si la ejecución fue exitosa.

Códigos de salida convencionales

Aunque Python no impone reglas estrictas sobre los códigos de salida, existen convenciones comunes:

import sys

# Códigos de salida comunes
EXIT_SUCCESS = 0       # Éxito
EXIT_FAILURE = 1       # Error general
EXIT_USAGE = 2         # Error de uso incorrecto (argumentos)
EXIT_DATA_ERROR = 65   # Error en los datos de entrada
EXIT_NO_INPUT = 66     # No se puede abrir la entrada
EXIT_NO_USER = 67      # Usuario no existe

# Ejemplo de uso
def validar_usuario(nombre):
    usuarios_validos = ["admin", "usuario1", "usuario2"]
    
    if not nombre:
        print("Error: Debe proporcionar un nombre de usuario")
        sys.exit(EXIT_USAGE)
        
    if nombre not in usuarios_validos:
        print(f"Error: El usuario '{nombre}' no existe")
        sys.exit(EXIT_NO_USER)
    
    return True

# Uso del programa
if len(sys.argv) < 2:
    print("Uso: python script.py <usuario>")
    sys.exit(EXIT_USAGE)

validar_usuario(sys.argv[1])
print("Usuario válido, continuando...")
sys.exit(EXIT_SUCCESS)

Capturando la salida con try/except

Cuando llamamos a sys.exit(), Python internamente lanza una excepción SystemExit que podemos capturar si es necesario:

import sys

def operacion_peligrosa():
    # Simular una operación que podría fallar
    valor = input("Ingrese un número (o 'salir' para terminar): ")
    
    if valor.lower() == 'salir':
        print("Saliendo por solicitud del usuario...")
        sys.exit(0)
        
    try:
        numero = int(valor)
        return 100 / numero
    except ValueError:
        print("Error: Debe ingresar un número válido")
        sys.exit(1)
    except ZeroDivisionError:
        print("Error: No se puede dividir por cero")
        sys.exit(2)

# Capturar la salida del programa
try:
    resultado = operacion_peligrosa()
    print(f"Resultado: {resultado}")
except SystemExit as e:
    codigo_salida = e.code
    print(f"El programa intentó salir con código: {codigo_salida}")
    print("Realizando limpieza antes de salir...")
    # Aquí podríamos realizar operaciones de limpieza
    
    # Propagar la excepción para terminar realmente
    raise

Esta técnica es útil cuando necesitamos realizar operaciones de limpieza antes de que el programa termine, como cerrar conexiones a bases de datos o liberar recursos.

Flujos de salida estándar

El módulo sys proporciona acceso a los flujos estándar que podemos usar para controlar dónde se envía la salida:

import sys

# Escribir en la salida estándar (stdout)
sys.stdout.write("Este es un mensaje normal\n")

# Escribir en la salida de error (stderr)
sys.stderr.write("Este es un mensaje de error\n")

# Redirigir temporalmente stdout a un archivo
stdout_original = sys.stdout
try:
    with open('registro.log', 'w') as archivo_log:
        sys.stdout = archivo_log
        print("Este mensaje va al archivo de registro")
        
        # Podemos seguir usando stderr para errores
        sys.stderr.write("Este error sigue yendo a la consola\n")
finally:
    # Restaurar stdout
    sys.stdout = stdout_original

print("De vuelta a la consola")

La separación entre stdout y stderr es especialmente útil cuando queremos filtrar o redirigir diferentes tipos de salida:

# En la línea de comandos podemos hacer:
# python script.py > salida.txt 2> errores.txt

Flush de la salida

A veces, la salida puede quedar almacenada en un buffer y no mostrarse inmediatamente. Podemos forzar la escritura con flush():

import sys
import time

# Simulación de una operación larga con progreso
for i in range(10):
    sys.stdout.write(f"Procesando... {i*10}%\r")
    sys.stdout.flush()  # Forzar la escritura inmediata
    time.sleep(0.5)

sys.stdout.write("Procesamiento completado!   \n")

En Python 3, también podemos usar el parámetro flush de la función print():

for i in range(10):
    print(f"Procesando... {i*10}%", end='\r', flush=True)
    time.sleep(0.5)

print("Procesamiento completado!   ")

Supresión de la salida

En ocasiones, queremos suprimir temporalmente toda la salida de un programa o función:

import sys
import os
from contextlib import contextmanager

@contextmanager
def suprimir_salida():
    """Contexto que suprime temporalmente stdout y stderr."""
    # Guardar los descriptores originales
    stdout_original = sys.stdout
    stderr_original = sys.stderr
    
    # Redirigir a /dev/null (o NUL en Windows)
    devnull = open(os.devnull, 'w')
    sys.stdout = devnull
    sys.stderr = devnull
    
    try:
        yield
    finally:
        # Restaurar los descriptores originales
        sys.stdout = stdout_original
        sys.stderr = stderr_original
        devnull.close()

# Ejemplo de uso
def funcion_ruidosa():
    print("¡Mensaje muy ruidoso!")
    print("¡Otro mensaje!")
    return 42

# Con salida normal
resultado1 = funcion_ruidosa()
print(f"Resultado 1: {resultado1}")

# Con salida suprimida
with suprimir_salida():
    resultado2 = funcion_ruidosa()

print(f"Resultado 2: {resultado2}")

Captura y análisis de la salida

Podemos capturar la salida de una función para analizarla o procesarla:

import sys
from io import StringIO

def capturar_salida(funcion, *args, **kwargs):
    """Ejecuta una función y captura su salida stdout."""
    # Guardar stdout original
    stdout_original = sys.stdout
    
    # Crear un buffer en memoria para capturar la salida
    buffer_salida = StringIO()
    sys.stdout = buffer_salida
    
    try:
        # Ejecutar la función
        resultado = funcion(*args, **kwargs)
        
        # Obtener la salida capturada
        salida = buffer_salida.getvalue()
        
        return resultado, salida
    finally:
        # Restaurar stdout
        sys.stdout = stdout_original

# Función de ejemplo que genera salida
def analizar_datos(valores):
    total = sum(valores)
    promedio = total / len(valores)
    
    print(f"Análisis de {len(valores)} valores:")
    print(f"- Total: {total}")
    print(f"- Promedio: {promedio:.2f}")
    print(f"- Máximo: {max(valores)}")
    print(f"- Mínimo: {min(valores)}")
    
    return {
        "total": total,
        "promedio": promedio,
        "maximo": max(valores),
        "minimo": min(valores)
    }

# Capturar y procesar la salida
datos = [12, 45, 3, 67, 34, 21]
resultado, salida = capturar_salida(analizar_datos, datos)

print("\nResultado de la función:")
print(resultado)

print("\nSalida capturada:")
print(salida)

# Podríamos analizar la salida, por ejemplo:
lineas = salida.strip().split('\n')
print(f"\nNúmero de líneas en la salida: {len(lineas)}")

Ejemplo práctico: Herramienta de línea de comandos

Veamos un ejemplo más completo que integra varias técnicas de control de salida:

import sys
import os
import time
import json

class Procesador:
    def __init__(self, archivo_entrada, archivo_salida=None, verbose=False):
        self.archivo_entrada = archivo_entrada
        self.archivo_salida = archivo_salida
        self.verbose = verbose
        self.estadisticas = {
            "lineas_procesadas": 0,
            "errores": 0,
            "tiempo_inicio": time.time(),
            "tiempo_fin": None
        }
    
    def log(self, mensaje, es_error=False):
        """Registra un mensaje según el nivel de verbosidad."""
        if es_error:
            sys.stderr.write(f"ERROR: {mensaje}\n")
            sys.stderr.flush()
        elif self.verbose:
            sys.stdout.write(f"INFO: {mensaje}\n")
            sys.stdout.flush()
    
    def procesar(self):
        """Procesa el archivo de entrada."""
        self.log(f"Iniciando procesamiento de '{self.archivo_entrada}'")
        
        try:
            if not os.path.exists(self.archivo_entrada):
                self.log(f"El archivo '{self.archivo_entrada}' no existe", es_error=True)
                return sys.exit(2)
            
            with open(self.archivo_entrada, 'r') as entrada:
                # Preparar salida
                if self.archivo_salida:
                    salida = open(self.archivo_salida, 'w')
                else:
                    salida = sys.stdout
                
                try:
                    # Procesar línea por línea
                    for i, linea in enumerate(entrada):
                        try:
                            # Simular procesamiento (convertir a mayúsculas)
                            resultado = linea.upper()
                            
                            # Escribir resultado
                            salida.write(resultado)
                            
                            # Actualizar estadísticas
                            self.estadisticas["lineas_procesadas"] += 1
                            
                            # Mostrar progreso
                            if self.verbose and i % 100 == 0:
                                self.log(f"Procesadas {i+1} líneas...")
                                
                        except Exception as e:
                            self.log(f"Error al procesar línea {i+1}: {e}", es_error=True)
                            self.estadisticas["errores"] += 1
                finally:
                    # Cerrar archivo de salida si no es stdout
                    if self.archivo_salida:
                        salida.close()
            
            # Registrar tiempo de finalización
            self.estadisticas["tiempo_fin"] = time.time()
            duracion = self.estadisticas["tiempo_fin"] - self.estadisticas["tiempo_inicio"]
            
            # Mostrar resumen
            self.log(f"Procesamiento completado en {duracion:.2f} segundos")
            self.log(f"Líneas procesadas: {self.estadisticas['lineas_procesadas']}")
            
            if self.estadisticas["errores"] > 0:
                self.log(f"Se encontraron {self.estadisticas['errores']} errores", es_error=True)
                return sys.exit(1)
            
            return sys.exit(0)
            
        except KeyboardInterrupt:
            self.log("\nProcesamiento interrumpido por el usuario", es_error=True)
            return sys.exit(130)  # Código estándar para SIGINT
        except Exception as e:
            self.log(f"Error fatal: {e}", es_error=True)
            return sys.exit(1)

def main():
    # Procesar argumentos
    if len(sys.argv) < 2:
        sys.stderr.write("Uso: python script.py <archivo_entrada> [archivo_salida] [--verbose]\n")
        sys.exit(2)
    
    archivo_entrada = sys.argv[1]
    archivo_salida = None
    verbose = False
    
    # Procesar argumentos opcionales
    for arg in sys.argv[2:]:
        if arg == "--verbose" or arg == "-v":
            verbose = True
        elif not arg.startswith("-"):
            archivo_salida = arg
    
    # Ejecutar procesador
    procesador = Procesador(archivo_entrada, archivo_salida, verbose)
    procesador.procesar()

if __name__ == "__main__":
    main()

Este script puede usarse de varias formas:

# Procesar un archivo y mostrar resultado en la consola
python procesador.py datos.txt

# Procesar un archivo y guardar resultado en otro archivo
python procesador.py datos.txt resultado.txt

# Procesar con mensajes informativos
python procesador.py datos.txt --verbose

# Redirigir la salida estándar a un archivo
python procesador.py datos.txt > resultado.txt

# Redirigir los errores a un archivo separado
python procesador.py datos.txt 2> errores.log

Mejores prácticas para la salida del programa

Al trabajar con la salida del programa, es recomendable seguir estas prácticas:

  • Usa códigos de salida consistentes para indicar diferentes tipos de errores.
  • Separa claramente los mensajes informativos (stdout) de los mensajes de error (stderr).
  • Proporciona mensajes de error descriptivos que ayuden a diagnosticar problemas.
  • Implementa diferentes niveles de verbosidad para controlar la cantidad de información mostrada.
  • Considera el entorno donde se ejecutará tu programa (terminal interactiva, script automatizado, etc.).
  • Maneja adecuadamente las interrupciones del usuario (como Ctrl+C).
  • Realiza limpieza de recursos antes de terminar el programa.
import sys
import signal
import atexit

# Registrar función de limpieza
def limpiar():
    print("Realizando limpieza final...")
    # Cerrar archivos, conexiones, etc.

atexit.register(limpiar)

# Manejar señales de interrupción
def manejador_interrupcion(signum, frame):
    print("\nInterrumpido por el usuario")
    # La limpieza se realizará automáticamente por atexit
    sys.exit(130)

signal.signal(signal.SIGINT, manejador_interrupcion)

# Ejemplo de programa principal
print("Programa en ejecución. Presiona Ctrl+C para interrumpir.")
try:
    # Simulación de trabajo
    for i in range(10):
        print(f"Trabajando... {i+1}/10")
        # Hacer algo útil aquí
        import time
        time.sleep(1)
    
    print("Trabajo completado con éxito")
    sys.exit(0)
except Exception as e:
    print(f"Error inesperado: {e}", file=sys.stderr)
    sys.exit(1)

El control adecuado de la salida del programa es fundamental para crear aplicaciones robustas y fáciles de usar, especialmente cuando se desarrollan herramientas de línea de comandos o scripts que formarán parte de flujos de trabajo automatizados.

Aprende Python online

Otros ejercicios de programación de Python

Evalúa tus conocimientos de esta lección Módulo sys con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Módulo math

Python
Puzzle

Reto herencia

Python
Código

Excepciones

Python
Test

Introducción a Python

Python
Test

Reto variables

Python
Código

Funciones Python

Python
Puzzle

Reto funciones

Python
Código

Módulo datetime

Python
Test

Reto acumulación

Python
Código

Reto estructuras condicionales

Python
Código

Polimorfismo

Python
Test

Módulo os

Python
Test

Reto métodos dunder

Python
Código

Diccionarios

Python
Puzzle

Reto clases y objetos

Python
Código

Reto operadores

Python
Código

Operadores

Python
Test

Estructuras de control

Python
Puzzle

Funciones lambda

Python
Test

Reto diccionarios

Python
Código

Reto función lambda

Python
Código

Encapsulación

Python
Puzzle

Reto coleciones

Python
Proyecto

Reto funciones auxiliares

Python
Código

Crear módulos y paquetes

Python
Puzzle

Módulo datetime

Python
Puzzle

Excepciones

Python
Puzzle

Operadores

Python
Puzzle

Diccionarios

Python
Test

Reto map, filter

Python
Código

Reto tuplas

Python
Código

Proyecto gestor de tareas CRUD

Python
Proyecto

Tuplas

Python
Puzzle

Variables

Python
Puzzle

Tipos de datos

Python
Puzzle

Conjuntos

Python
Test

Reto mixins

Python
Código

Módulo csv

Python
Test

Módulo json

Python
Test

Herencia

Python
Test

Análisis de datos de ventas con Pandas

Python
Proyecto

Reto fechas y tiempo

Python
Proyecto

Reto estructuras de iteración

Python
Código

Funciones

Python
Test

Reto comprehensions

Python
Código

Variables

Python
Test

Reto serialización

Python
Proyecto

Módulo csv

Python
Puzzle

Reto polimorfismo

Python
Código

Polimorfismo

Python
Puzzle

Clases y objetos

Python
Código

Reto encapsulación

Python
Código

Estructuras de control

Python
Test

Importar módulos y paquetes

Python
Test

Módulo math

Python
Test

Funciones lambda

Python
Puzzle

Reto excepciones

Python
Código

Listas

Python
Puzzle

Reto archivos

Python
Proyecto

Encapsulación

Python
Test

Reto conjuntos

Python
Código

Clases y objetos

Python
Test

Instalación de Python y creación de proyecto

Python
Test

Reto listas

Python
Código

Tipos de datos

Python
Test

Crear módulos y paquetes

Python
Test

Tuplas

Python
Test

Herencia

Python
Puzzle

Reto acceso a sistema

Python
Proyecto

Proyecto sintaxis calculadora

Python
Proyecto

Importar módulos y paquetes

Python
Puzzle

Clases y objetos

Python
Puzzle

Módulo os

Python
Puzzle

Listas

Python
Test

Conjuntos

Python
Puzzle

Reto tipos de datos

Python
Código

Reto matemáticas

Python
Proyecto

Módulo json

Python
Puzzle

Todas las lecciones de Python

Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Python

Python

Introducción

Instalación Y Creación De Proyecto

Python

Introducción

Tema 2: Tipos De Datos, Variables Y Operadores

Python

Introducción

Instalación De Python

Python

Introducción

Tipos De Datos

Python

Sintaxis

Variables

Python

Sintaxis

Operadores

Python

Sintaxis

Estructuras De Control

Python

Sintaxis

Funciones

Python

Sintaxis

Estructuras Control Iterativo

Python

Sintaxis

Estructuras Control Condicional

Python

Sintaxis

Testing Con Pytest

Python

Sintaxis

Listas

Python

Estructuras De Datos

Tuplas

Python

Estructuras De Datos

Diccionarios

Python

Estructuras De Datos

Conjuntos

Python

Estructuras De Datos

Comprehensions

Python

Estructuras De Datos

Clases Y Objetos

Python

Programación Orientada A Objetos

Excepciones

Python

Programación Orientada A Objetos

Encapsulación

Python

Programación Orientada A Objetos

Herencia

Python

Programación Orientada A Objetos

Polimorfismo

Python

Programación Orientada A Objetos

Mixins Y Herencia Múltiple

Python

Programación Orientada A Objetos

Métodos Especiales (Dunder Methods)

Python

Programación Orientada A Objetos

Composición De Clases

Python

Programación Orientada A Objetos

Funciones Lambda

Python

Programación Funcional

Aplicación Parcial

Python

Programación Funcional

Entrada Y Salida, Manejo De Archivos

Python

Programación Funcional

Decoradores

Python

Programación Funcional

Generadores

Python

Programación Funcional

Paradigma Funcional

Python

Programación Funcional

Composición De Funciones

Python

Programación Funcional

Funciones Orden Superior Map Y Filter

Python

Programación Funcional

Funciones Auxiliares

Python

Programación Funcional

Reducción Y Acumulación

Python

Programación Funcional

Archivos Comprimidos

Python

Entrada Y Salida Io

Entrada Y Salida Avanzada

Python

Entrada Y Salida Io

Archivos Temporales

Python

Entrada Y Salida Io

Contexto With

Python

Entrada Y Salida Io

Módulo Csv

Python

Biblioteca Estándar

Módulo Json

Python

Biblioteca Estándar

Módulo Datetime

Python

Biblioteca Estándar

Módulo Math

Python

Biblioteca Estándar

Módulo Os

Python

Biblioteca Estándar

Módulo Re

Python

Biblioteca Estándar

Módulo Random

Python

Biblioteca Estándar

Módulo Time

Python

Biblioteca Estándar

Módulo Collections

Python

Biblioteca Estándar

Módulo Sys

Python

Biblioteca Estándar

Módulo Statistics

Python

Biblioteca Estándar

Módulo Pickle

Python

Biblioteca Estándar

Módulo Pathlib

Python

Biblioteca Estándar

Importar Módulos Y Paquetes

Python

Paquetes Y Módulos

Crear Módulos Y Paquetes

Python

Paquetes Y Módulos

Entornos Virtuales (Virtualenv, Venv)

Python

Entorno Y Dependencias

Gestión De Dependencias (Pip, Requirements.txt)

Python

Entorno Y Dependencias

Python-dotenv Y Variables De Entorno

Python

Entorno Y Dependencias

Acceso A Datos Con Mysql, Pymongo Y Pandas

Python

Acceso A Bases De Datos

Acceso A Mongodb Con Pymongo

Python

Acceso A Bases De Datos

Acceso A Mysql Con Mysql Connector

Python

Acceso A Bases De Datos

Novedades Python 3.13

Python

Características Modernas

Operador Walrus

Python

Características Modernas

Pattern Matching

Python

Características Modernas

Instalación Beautiful Soup

Python

Web Scraping

Sintaxis General De Beautiful Soup

Python

Web Scraping

Tipos De Selectores

Python

Web Scraping

Web Scraping De Html

Python

Web Scraping

Web Scraping Para Ciencia De Datos

Python

Web Scraping

Autenticación Y Acceso A Recursos Protegidos

Python

Web Scraping

Combinación De Selenium Con Beautiful Soup

Python

Web Scraping

Accede GRATIS a Python y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender cómo acceder y procesar argumentos de línea de comandos con sys.argv.
  • Conocer las variables y funciones del módulo sys para interactuar con el intérprete y el sistema operativo.
  • Aprender a gestionar y modificar las rutas de importación de módulos mediante sys.path.
  • Controlar la salida del programa y la terminación con sys.exit(), así como manejar flujos estándar de entrada y salida.
  • Aplicar buenas prácticas para el manejo de argumentos, rutas y salida en programas Python.