Metaprogramación en python

Citando a wikipedia, por que todos sabemos que  wikipedia siempre tiene la razón.

La metaprogramación consiste en escribir programas que escriben o manipulan otros programas (o a sí mismos) como datos, o que hacen en tiempo de compilación parte del trabajo que, de otra forma, se haría en tiempo de ejecución.

Lamentablemente la definición de metaprogramación es tan ambigua que un montón de estupideces se pueden considerar metraprorgramación. En el sentido mas estricto del termino, podemos escribir un programa que escriba otro programa que imprima 100 números. El cual no tiene ningún funcionamiento mas allá de lo académico,  una forma poco practica de enseñar que es un for y que es un if.

En un ejemplo un poco mas practico, podemos hacer que un programa nos construya los esqueletos de un programa mas grande. Se adapta al termino, pero deja la cuestión de si  eso es metaprogramar. Tal vez el termino es demasiado “nice” para lo que realmente es la metaprogramación.

Un ejemplo mas real es el migrations de django, el sistema construye código de referencia para poder modificar posteriormente la base de datos. Eso si es realmente ingenioso.

¿Entonces que es la metaprogramación?

El prefijo meta se indica para  expresar un concepto abstracto de otro concepto, algo revuelto, lo se. En otras palabras el prefijo meta significa “mas allá” o “después de”, ¿aún difícil de captar?. De alguna forma podría decirse que que el concepto trasciende el significado original. En este caso la metaprogramación podría ser lo que esta mas allá del programa o lo que es superior en concepto al programa. También podríamos decir que es un programa que reflexiona sobre si mismo.

Metaprogramemos a la altura de una definición tan “nice”

En términos menos mortales y mas específicamente en python. Al menos para mi, un metaprograma es un programa que puede manipular sus clases  o construir nuevas clases en tiempo de ejecución. En otras palabras, una clase es un fragmento de código escrito y en python tenemos la particularidad de que podemos crear clases en tiempo de ejecución sin tener un código escrito.

Pero de la teoría a la practica es muy difícil encontrar un ejemplo real de donde aplicar la metaprogramación.  Yo  al menos una vez la pude usar en un ambiente de pruebas de un CMS.

Ejemplo Practico

Teníamos un sistema donde podíamos agregar nuevos tipos de datos en cualquier momento, en este caso era un CMS que por algún motivo, el dueño pedía poder construir  nuevos bloques HTML de cosas muy abstractas, por ejemplo: frutas, coches,  películas, etc.

Por un momento recordé el método type, es un método cuya función es devolver el tipo de dato de una variable, pero también puede ser usado para crear nuevos tipos de datos, en otras palabras CLASES.

Siendo así, es posible crear un tipo de dato que extienda de la clase “models.Model” de django,  pedirle a Django que lo sincronice con la base de datos y registrarlo en el administrador. Entonces, tendríamos una  nueva interfaz para un nuevo modelo y una tabla nueva en la base de datos, para algo que no existe en código y que nunca llegara a existir de forma escrita..

¿Interesante no? es un buen experimento, así que no pondré el código aquí, pero les daré varias pistas:

  • Puedes crear dos modelos, uno para guardar el nombre de la clase y otro para guardar sus atributos.
  • Puedes cargar nuevos modelos al admin en tiempo de ejecución, por ejemplo puedes cargar un nuevo modelo en el save de otro modelo.
  • Puedes instancias las clases virtuales con cada nuevo “runserver” para siempre tenerlas presentes, después de todo la definición esta en una base de datos.

 

Martin Quinta

Crecí con una computadora desde el kinder. Empece a programar a los 14 y hoy, mas de una década después… realmente odio estar frente a una computadora. Pero programar es en lo que soy bueno, por lo tanto me desahogo en este blog mientras bebo cerveza artesanal y pienso en un mundo bonito donde Java no existe.

Facebook Twitter LinkedIn  

Entradas relacionadas:

Leave a Reply

Your email address will not be published. Required fields are marked *