2008-08-08 18 views
13

Básicamente, escribí una API para www.thetvdb.com en Python. El código actual se puede encontrar here.La mejor forma de resumir datos de temporada/show/episodio

Se agarra a los datos de la API a lo solicitado, y tiene que almacenar los datos de alguna manera, y ponerla a disposición haciendo:

print tvdbinstance[1][23]['episodename'] # get the name of episode 23 of season 1 

¿Cuál es el "mejor" forma de abstraer estos datos dentro de la clase Tvdb() ?

originalmente utilizó un prolongado Dict() que crea automáticamente sub-dicts (por lo que podría hacer x[1][2][3][4] = "something" sin tener que hacer if x[1].has_key(2): x[1][2] = [] y así sucesivamente)

Entonces sólo almacena los datos haciendo self.data[show_id][season_number][episode_number][attribute_name] = "something"

Esto funcionó está bien, pero no había una manera fácil de comprobar si se suponía que x[3][24] existía o no (así que no pude subir la excepción season_not_found).

Actualmente se trata de utilizar cuatro clases: ShowContainer, Show, Season y Episode. Cada uno es un dict muy básico, en el que puedo agregar funcionalidad extra fácilmente (la función search() en Show() por ejemplo). Cada uno tiene un __setitem__, __getitem_ y has_key.

Esto funciona en su mayoría bien, puedo comprobar en espectáculos si tiene esa temporada en self.data dict, si no, raise season_not_found. También puedo registrarme en Season() si tiene ese episodio y así sucesivamente.

El problema ahora es que es presentarse como un diccionario, pero no tiene toda la funcionalidad, y porque estoy anulando los __getitem__ y __setitem__ funciones, es fácil accidentalmente de forma recursiva llamar __getitem__ (así que no estoy seguro si extender la clase Dict causará problemas).

El otro problema leve es agregar datos en el dict es mucho más trabajo que el viejo método Dict (que era self.data[seas_no][ep_no]['attribute'] = 'something'). Ver _setItem y _setData. No es tan malo, ya que actualmente es solo una interfaz API de solo lectura (por lo que los usuarios de la API solo deberían recuperar datos, no agregar más), pero es difícil ... Elegante.

Creo que el sistema de series de clases es probablemente la mejor manera, pero ¿alguien tiene una mejor idea para almacenar los datos? ¿Y la ampliación de las clases ShowContainer/etc con Dict causa problemas?

Respuesta

5

bien, lo que necesita es classobj del nuevo módulo. Eso le permitiría construir clases de excepción dinámicamente (classobj toma una cadena como argumento para el nombre de clase).

import new 
myexc=new.classobj("ExcName",(Exception,),{}) 
i=myexc("This is the exc msg!") 
raise i 

esto le da:

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
__main__.ExcName: This is the exc msg! 

recuerde que siempre puede obtener el nombre de la clase a través de:

self.__class__.__name__ 

Así, después de un poco de hilo y para dar la concatenación, que debe ser capaz de obtenga el nombre de la clase de excepción apropiada y construya un objeto de clase usando ese nombre y luego eleve esa excepción.

P.S.- También puedes subir cadenas, pero esto está en desuso.

raise(self.__class__.__name__+"Exception") 
3

¿Por qué no utilizar SQLite? Existe un buen soporte en Python y puede escribir consultas SQL para obtener los datos. Aquí está la documentación de Python para sqlite3


Si no desea utilizar SQLite que podría hacer una gran variedad de dicts.

episodes = [] 
episodes.append({'season':1, 'episode': 2, 'name':'Something'}) 
episodes.append({'season':1, 'episode': 2, 'name':'Something', 'actors':['Billy Bob', 'Sean Penn']}) 

De esta forma se agrega metadatos a cualquier registro y buscar muy fácilmente

season_1 = [e for e in episodes if e['season'] == 1] 
billy_bob = [e for e in episodes if 'actors' in e and 'Billy Bob' in e['actors']] 

for episode in billy_bob: 
    print "Billy bob was in Season %s Episode %s" % (episode['season'], episode['episode']) 
0

he hecho algo similar en el pasado y se utiliza un documento XML en memoria como una base de datos jerárquica rápida y sucia para almacenamiento. Puede almacenar cada show/season/episode como un elemento (anidado apropiadamente) y atributos de estos elementos como atributos xml en los elementos. Luego puede usar XQuery para obtener información de nuevo.

NOTA: No soy un chico de Python, así que no sé cómo es su soporte xml.

NOTA 2: Querrá hacer un perfil de esto porque será más grande y más lento que la solución que ya tiene. Probablemente si estás haciendo un procesamiento de alto volumen, entonces XML probablemente no sea tu amigo.

0

No entiendo esta parte aquí:

Esto funcionó bien, pero no había manera fácil de comprobar si [3] [24] Se suponía x existir o no (por lo que no pude t elevar la excepción season_not_found)

Hay una manera de hacerlo - llamada en:

>>>x={} 
>>>x[1]={} 
>>>x[1][2]={} 
>>>x 
{1: {2: {}}} 
>>> 2 in x[1] 
True 
>>> 3 in x[1] 
False 

lo que parece ser el problema ¿con ese?

0

Bartosz/Para aclarar "Esto funcionó bien, pero no había manera fácil de comprobar si [3] [24] Se suponía x existir o no"

x['some show'][3][24] volvería temporada 3, episodio 24 de " algunos muestran ". Si no hubo temporada 3, quiero que el pseudo-dict aumente tvdb_seasonnotfound, si "algún espectáculo" no existe, entonces aumente tvdb_shownotfound

El sistema actual de una serie de clases, cada una con un __getitem__ - Mostrar cheques if self.seasons.has_key(requested_season_number), la clase de temporada comprueba if self.episodes.has_key(requested_episode_number) y así sucesivamente.

Funciona, pero parece que hay una gran cantidad de código repetido (cada clase es básicamente el mismo, pero plantea un error diferente)

Cuestiones relacionadas