Reflexión e Introspección en la Programación Orientada a Objetos con Python

La reflexión implica tratar los nombres de atributos y métodos como datos de tipo string, lo que permite operaciones flexibles cuando los nombres no se conocen de antemano, como en entradas de usuario. Esto se logra mediante funciones integradas que facilitan la introspección y la manipulación de objetos.

Funciones Integradas Clave

Las siguientes funciones de Python son fundamentales para la reflexión:

  • hasattr(objeto, nombre_str): Verifica si un objeto posee un atributo o método cuyo nombre coincide con la cadena proporcionada.
  • getattr(objeto, nombre_str): Obtiene el valor de un atributo o la referencia a un método basado en su nombre como cadena.
  • setattr(objeto, nombre_str, valor): Establece o modifica un atributo en el objeto, usando el nombre dado como cadena.
  • delattr(objeto, nombre_str): Elimina un atributo del objeto según su nombre en forma de cadena.

Para ilustrar, consideremos un ejemplo donde un usuario interactúa con un objeto a través de una entrada de cadena. Primero, definimos una clase con algunos atirbutos y métodos:


class EjemploClase:
    institucion = 'Universidad Ejemplo'

    def iniciar_sesion(self):
        print('El usuario ha iniciado sesión correctamente.')

instancia = EjemploClase()
while True:
    nombre = input('Ingrese el nombre del atributo o método a buscar: ')
    if hasattr(instancia, nombre):
        print('El atributo o método existe en el objeto.')
        recurso = getattr(instancia, nombre)
        if callable(recurso):
            print('Se ha detectado un método invocable.')
            recurso()
        else:
            print('Se ha detectado un atributo con valor:')
            print(recurso)
    else:
        print('El atributo o método no se encuentra en el objeto.')

Este código permite al usuario buscar y operar sobre atributos o métodos de manera dinámica. La función hasattr verifica la existencia, y getattr recupera el recurso correspondiente, diferenciando entre datos y funciones invocables.

Aplicación Práctica: Simulación de una Terminal de Comandos

Otro caso de uso es la emulación de una interfaz de línea de comandos, donde los comandos ingresados como cadenas se mapean a métodos internos. A continuación, se muestra una clace que simula operaciones básicas:


class SimuladorTerminal:
    def __listar_procesos(self):
        print('Procesos activos: calculadora, editor, navegador.')

    def __mostrar_red(self):
        print('Configuración de red: IP 192.168.1.100, Máscara 255.255.255.0.')

    def __abrir_archivo(self, archivo):
        print(f'Abriendo archivo: {archivo}')

    def __enviar_archivo(self, archivo, destino):
        print(f'Enviando {archivo} al destino {destino}')

    def ejecutar(self):
        while True:
            entrada = input('Ingrese comando (salir para terminar): ').strip()
            if entrada == 'salir':
                break
            partes = entrada.split()
            comando_principal = f'_SimuladorTerminal__{partes[0]}'
            if hasattr(self, comando_principal):
                metodo = getattr(self, comando_principal)
                if len(partes) == 1:
                    metodo()
                elif len(partes) > 1:
                    metodo(*partes[1:])
            else:
                print('Comando no reconocido.')

simulador = SimuladorTerminal()
simulador.ejecutar()

En este ejemplo, los comandos como listar o mostrar_red se transforman dinámicamente en nombres de métodos internos (prefijados con la clase para simular encapsulamiento). Esto demuestra cómo la reflexión permite adaptar el flujo del programa basado en entradas variibles, manteniendo la modularidad y extensibilidad.

Etiquetas: Python POO reflexión introspección hasattr

Publicado el 7-2 01:01