Trasteando con mi código, en cierto momento (culpa de las plantillas de Django) me dí cuenta de que perdía una gran cantidad de tiempo declarando clases "auxiliares", que solo iba a usar una vez. Tiempo después, y quizás influenciado por la filosofía del Javascript, encontré una rápida solución: implementar clases a partir de diccionarios.
class DictClass(dict):
def __getattribute__(self,i):
if i[0:2] != "__" and self.__contains__(i):
return self.__getitem__(i)
return dict.__getattribute__(self,i)
Se usa muy fácilmente, en cualquier momento que quieras instanciar una clase, tan sólo tenemos que tratarlo como un diccionario. Pero sus atributos y método serán accesibles como si de una clase se tratase.
aux = DictClass({
"texto": "hola",
"method": lambda x:x+1,
})
aux["texto"] = "hasta la vista"
print(aux.texto)
Además, me he creado otra clase dinámica pero a partir de una lista, cuyos elementos son accesibles como si fuesen atributos (su utilidad se comenta al final).
import re
reitem = re_compile("^item_\d+$")
class ListClass(list):
def __getattribute__(self,i):
if reitem.match(i):
return self.__getitem__( int(i[5:]) )
return list.__getattribute__(self,i)
Y se usaría como una lista, cuyos valores son a su vez atributos.
lista = ListClass([1,2,3])
lista.append(4)
print(lista.item_4)
Tened en cuenta que esta técnica es menos eficiente que declarar las clases "tradicionales" desde el punto de vista del rendimiento, pero permite programar mucho mas rápido, y saltarse ciertas limitaciones del motor de plantillas de Django 1.0, que no permite acceder a las propiedades de los diccionarios y acceder a determinados valores de una lista, si no es a través de bucles.
<p>Valor de propiedad de DictClass: {{ clase.atributo }}</p>
<p>Valor de la primera posición de una lista: {{ lista.item_0 }}</p>
Espero que os haya sido de utilidad, no he descubierto la pólvora, y seguro que hay formas mejores o mas rápidas de ahorrarse tiempo de desarrollo (¿He oido Ruby por algún lado?), pero esto me ha sido muy útil ahorrándome un tercio de dicho tiempo, y por eso lo comparto.
0 comentarios:
Publicar un comentario