La capa de datos

A continuación se presenta el listado íntegro del módulo que implementa la capa de datos.

#agendadb.py
import anydbm        #Gestión de datos persistentes
import string        #Gestión de cadenas de texto
import pickle        #Conversión de objetos a cadena (serialización)

class agenda:
    def __init__(self,fich='agenda.db'):
        self.db=anydbm.open(fich,'c')    #Abrimos la BD al instanciar el objeto
    
    def encuentra(self, clave):            #Búsqueda rápida
        clave=string.upper(str(clave))
        try:
            #Recuperamos el objeto a partir de la representación interna
            return pickle.loads(self.db[clave])     
        except:
            #Si no se encuentra, se devuelve None (el nulo de Python)
            return None
        
    def busca(self, clave):        #Búsqueda lenta, por contenido
        ret=[]
        clave=string.upper(str(clave))
        for k in self.db.keys():
            if string.find(k,clave)>-1:
                #Añadimos el elemento al resultado
                ret.append( (k,pickle.loads(self.db[k])) )
        return ret
        
    def nuevo(self,clave,contenido):    #Nuevo elemento de la BD
        nombre=string.upper(str(clave))         #Las claves independientes de mays/minus
        picContenido=pickle.dumps(contenido)     #Convertimos lo que venga a cadena
        self.db[nombre]=picContenido             #Lo guardamos en la BD con su clave

if __name__=='__main__':        #No es un módulo, hacemos una prueba unitaria
    ag=agenda()
    if not ag.db:                 #Agenda vacía, metemos contenido inicial
        ag.nuevo('ErnestoBKE', ('Ernesto Molina','emolina@grupoburke.com'))
        ag.nuevo('Ernesto', ('Ernesto Molina','rotoxl@jazzfree.com'))
        ag.nuevo('MarcosBKE', ('Marcos Sánchez','msanchez@grupoburke.com'))
        ag.nuevo('Marcos', ('Marcos Sánchez','rapto@arrakis.es'))
    
    print ag.encuentra('Ernesto')     #Recuperamos unos cuantos datos
    print ag.busca('BKE')
    

Comentarios al listado

No se ha incluido en este módulo nada de código de interfaz, salvo lo trivial de print, que presenta en la consola texto sin formato.

El módulo pickle es responsable de la serialización, es decir, convertir a cadena (de manera reversible) cualquier objeto. pickle es muy flexible y normalmente funciona sin tener que preocuparse de cómo lo hace.

De momento, es posible pasar a la base de datos cualquier objeto y cualquier clave. Es costumbre en Python dejar cuantas más características posibles abiertas, para no restringir la utilidad de los módulos para un uso posterior.

Python dispone de interfaces de datos muy variadas, desde la interfaz minimalista que vemos aquí, hasta el acceso a servidores de datos multidimensionales. Cuenta con bibliotecas nativas para los servidores más comunes y con puentes con ODBC/JDBC para cubrir el resto de los servidores.

Si es la primera vez que ves un listado en Python, habrás observado que los niveles de anidamiento se marcan simplemente por el margen izquierdo.

No es necesario declarar las variables, aunque es ilegal utilizarlas sin asignarles anteriormente un valor. Los tipos de las variables en Python se determinan en el instante en que se definen asignándoles su valor.

Se utiliza el latiguillo if __name__=='__main__': para detectar que el módulo está actuando como programa autónomo. Se acostumbra a poner funciones de prueba del propio módulo en este caso (si el módulo no tiene una utilidad por sí solo).

El argumento self de los métodos indica el propio objeto, a la manera de this (Java) o Me (Visual Basic). En Python este argumento es explícito y no se puede omitir en ningún caso.