2008-08-08 9 views
13

Grundsätzlich habe ich eine API zu www.thetvdb.com in Python geschrieben. Der aktuelle Code kann here gefunden werden.Der beste Weg, um Staffel/Show/Episode Daten zu abstrahieren

Es packt Daten aus der API wie gewünscht, und hat die Daten irgendwie zu speichern und zur Verfügung zu stellen, indem Sie:

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

Was ist die „beste“ Art und Weise zu abstrahieren diesen Daten innerhalb der Tvdb() Klasse ?

habe ich ursprünglich einen erweiterten Dict(), die automatisch Unter dicts erstellt (so könnte man x[1][2][3][4] = "something" tun, ohne if x[1].has_key(2): x[1][2] = [] zu tun zu haben, und so weiter)

Dann habe ich die Daten nur gespeichert, indem self.data[show_id][season_number][episode_number][attribute_name] = "something"

tun Dies funktionierte Okay, aber es gab keine einfache Möglichkeit zu überprüfen, ob x[3][24] existieren sollte oder nicht (so konnte ich die season_not_found-Ausnahme nicht auslösen).

es derzeit mit vier Klassen: ShowContainer, Show, Season und Episode. Jedes ist ein sehr grundlegendes Diktat, dem ich leicht zusätzliche Funktionalität hinzufügen kann (die search() Funktion auf Show() zum Beispiel). Jeder hat eine __setitem__, __getitem_ und has_key.

Das funktioniert vor allem gut, ich kann einchecken, wenn es diese Saison hat, ist es self.data dict, wenn nicht, raise season_not_found. Ich kann auch einchecken Season(), wenn es diese Episode hat und so weiter.

Das Problem jetzt ist es, sich als dict ist präsentiert, aber nicht über alle Funktionen, und weil ich die __getitem__ und __setitem__ Funktionen überschreiben bin, ist es einfach __getitem__ versehentlich rekursiv zu nennen (so bin ich nicht sicher wenn die Erweiterung Dict Klasse Probleme verursacht).

Das andere kleine Problem ist das Hinzufügen von Daten in das Diktat ist viel mehr Arbeit als die alte Dict Methode (die war). Siehe _setItem und _setData. Es ist nicht so schlimm, da es derzeit nur eine schreibgeschützte API-Schnittstelle ist (also sollten die Benutzer der API nur Daten abrufen, nicht mehr hinzufügen), aber es ist kaum ... Elegant.

Ich denke, die Serie von Klassen-System ist wahrscheinlich der beste Weg, aber hat jemand eine bessere Idee für die Speicherung der Daten? Und würde die Erweiterung der ShowContainer/etc Klassen mit Dict Probleme verursachen?

Antwort

5

OK, was Sie brauchen, ist classobj von neuen Modul. Dadurch können Sie Ausnahmeklassen dynamisch erstellen (classobj nimmt eine Zeichenfolge als Argument für den Klassennamen an).

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

das gibt Ihnen:

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

daran erinnern, dass Sie immer die Klassennamen durchkommen:

self.__class__.__name__ 

So, nachdem einige String Mangeln und Verkettung, sollten Sie in der Lage sein, Ermitteln Sie den entsprechenden Namen der Ausnahmeklasse und erstellen Sie ein Klassenobjekt mit diesem Namen, und heben Sie diese Ausnahme auf.

P.S.- Sie können auch Zeichenfolgen erhöhen, dies ist jedoch veraltet.

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

Warum nicht SQLite verwenden? Es gibt eine gute Unterstützung in Python und Sie können SQL-Abfragen schreiben, um die Daten zu entfernen. Hier ist die Python-Dokumentation für sqlite3


Wenn Sie nicht SQLite verwenden möchten können Sie eine Reihe von dicts zu tun.

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

Auf diese Weise können Metadaten zu jedem Datensatz hinzufügen und suchen sehr leicht

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

ich etwas ähnliches in der Vergangenheit getan haben und verwendet, um eine In-Memory-XML-Dokument als quick and dirty hierarchisches Datenbank für die Lagerung. Sie können jede Show/Saison/Episode als ein Element (entsprechend verschachtelt) und Attribute dieser Dinge als XML-Attribute für die Elemente speichern. Dann können Sie XQuery verwenden, um Informationen wieder zu erhalten.

HINWEIS: Ich bin kein Python-Typ, also weiß ich nicht, wie Ihre xml-Unterstützung ist.

ANMERKUNG 2: Sie möchten dies profilieren, weil es größer und langsamer als die Lösung ist, die Sie bereits haben. Wahrscheinlich genug, wenn Sie eine High-Volume-Verarbeitung machen, wird XML wahrscheinlich nicht Ihr Freund sein.

0

ich diesen Teil nicht hier:

Diese Ordnung war, aber es war nicht einfach, wenn x die Überprüfung [3] [24] sollte existieren oder nicht (so couldn I‘ t erhöht die season_not_found Ausnahme)

es gibt einen Weg, es zu tun - genannt in:

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

, was das Problem scheint zu sein, damit?

0

Bartosz/Zur Klärung „Das funktionierte gut, aber es war keine einfache Möglichkeit, zu überprüfen, ob x [3] [24] sollte existieren oder nicht“

x['some show'][3][24] Saison zurückkehren würde 3, Folge 24 von " einige zeigen ". Wenn es keine Saison 3 war, möchte ich der pseudo-dict tvdb_seasonnotfound zu erhöhen, wenn „einig Show“ nicht vorhanden ist, dann heben tvdb_shownotfound

Das derzeitige System aus einer Reihe von Klassen, die jeweils mit einer __getitem__ - zeigen Kontrollen if self.seasons.has_key(requested_season_number), prüft die Season-Klasse if self.episodes.has_key(requested_episode_number) und so weiter.

Es funktioniert, aber es scheint, dass es eine Menge wiederholt Code zu sein (jede Klasse im Grunde die gleichen, aber wirft einen anderen Fehler)