Buscar este blog

viernes, 12 de abril de 2024

¿Es más fácil pedir perdón que permiso?

 



¿Controlar todas las condiciones o dejar que los errores ocurran e interceptarlos? El título de esta historia surge de un enfoque predominante en Python.

Esta ha sido otra semana accidentada en NLand.

El disco magnético de Pentaseutz, un Western Digital Green de 1TB, comenzó a dar problemas, como si se hubiera puesto celoso del nuevo SSD "AData" instalado hace diez días.

Tengo sospechas no fundadas de que al desperfecto lo haya precipitado el hecho de montar y acceder el disco (formateado con NTFS) desde Linux. Pero, como digo, no tengo fundamentos.

Por lo pronto, el viernes pasado Pentaseutz dejó de responder abruptamente, y el único signo de vida que la diferenciaba de una placa madre muerta era precisamente el logotipo de la placa base mostrado en el POST (Power On Self Test).

Sólo desconectando el disco rígido pudimos usar Pentaseutz nuevamente, con los dos SSD que tenían los 3 sistemas operativos instalados: Windows 11 (dos instalaciones, una la usa Clarise) y Lubuntu.

Por lo pronto todo sigue así, no he vuelto a conectarlo, pero deberé hacerlo en pocas horas porque dentro hay proyectos esperando.


El tema de hoy tiene que ver con Python y con enfoques a la hora de programar y lidiar con errores.

Explorando el Glosario en la documentación de Python encontré algo de lo que otros lenguajes no me hablaron, y me dije "debo tomar nota de esto".

¿Conocen el término Duck Typing?

Literalmente se traduce como "Tipado Pato" o "Tipado estilo pato". Esto viene de un refrán en inglés que dice "Si se ve como un pato y hace cuack, debe ser un pato".

Programar con orientación a objetos puede ser muy flexible y organizado.

Imaginemos un programa para poner figuras geométricas en la pantalla.

Una parte del programa recibe un objeto (que representa a la figura a dibujar). Averigua en qué punto de la pantalla se hizo click, averigua cuál es el color de línea y de relleno actuales, y luego invoca al método dibujar() del objeto que recibió.

¿En qué parte se ocupa de dibujar un cuadrado, un círculo o un triángulo? ¡En ninguna!

Eso es responsabilidad del objeto que recibe. Esta parte del programa sólo debe invocar el método dibujar().

El truco es que al definir cada clase (cuadrado, círculo, triángulo) programaremos su propio método dibujar() para que haga lo que necesitamos.

Si en el futuro agregamos la capacidad de dibujar un pentágono, sólo debemos concentrarnos en crear la clase Pentagon y que tenga un método dibujar() que logre darnos un pentágono. El resto del programa no cambia, no se entera de nada, no debe modificarse, no nos quitará tiempo. Esa parte seguirá llamando al método dibujar() de cualquier objeto que le enviemos.

La pregunta es: ¿podemos confiar en que no fallará?

Bueno, según el Duck Typing, si tiene un método dibujar() y dibuja, debe ser un pato. Mejor dicho, un objeto de figura geométrica.

¿Y si no?

La idea del Duck Typing es no usar funciones como type() para saber el tipo de un objeto, ni isinstance() para consultar si un objeto pertenece a una clase determinada. Cosas que, por otra parte, parecerían precauciones razonables para saber si se puede o no intentar hacer algo con un objeto.

Pero, tal vez tenga razón. Controlar que todo esté en orden puede ser estresante, producir mucho código adicional y a veces puede que no podamos prever todos los errores, por olvidarlo o porque simplemente no se sabe qué controlar.

En lugar de eso, propone un uso intensivo de funciones como hasattr() (para saber si un atributo o método está disponible) y de EAFP.

EAFP proviene de otro dicho común en inglés: "Easier to ask for forgiveness than permission" (Es más fácil pedir perdón que permiso).

Es un estilo de programación rápido y limpio, que asume la existencia de los atributos necesarios. Se caracteriza por la abundancia de sentencias try y except para interceptar los errores que pudieran ocurrir.

Lo contrario también tiene un nombre: LBYL (Look before you leap, "mira antes de saltar"), y se considera una práctica propia de C más que de Python. Se caracteriza por realizar muchas verificaciones con if para verificar que estén dadas todas las condiciones.

Eso hice en toda mi carrera.

Desde el punto de vista de Python se considera mejor usar try, except y EAFP.

Hasta aquí la historia de hoy. No quiero demorarlos con un extenso tutorial y sé que los lectores buscarán por su cuenta si les interesa.

Mi conclusión

Me queda como aprendizaje lo que vimos sobre Duck Typing, ese método de programación optimista que confía en que las condiciones están dadas y se prepara a interceptar las excepciones.

PERO, si me piden una opinión, creo que no podemos escapar al "Destino Final" (si no conocen las películas de la serie Final Destiny, vean alguna. Yo no lo haría, la ficción no me atrae y menos si es de terror.)

El enfoque LBYL propone anticiparse a cualquier condición de error. El enfoque EAFP propone reaccionar a cualquier condición de error. Antes o después, deberemos programar acciones para errores conocidos y acciones para errores desconocidos.

Ahora bien. Mi opinión es que el enfoque EAFP al menos nos permitirá percatarnos de que hubo un error. Si actuamos según LBYL, verificaremos una serie de condiciones y si todo está bien procederemos asumiendo que nada puede fallar. Y tal vez falle.

EAFP está siempre atento a los errores que ocurran. Mínimamente, se enterará. Porque se ejecutará una excepción.

Así soy yo. Nunca garantizo el éxito y estoy escuchando posibles errores.

Me dicen que soy inseguro.



No hay comentarios.:

Publicar un comentario