Frage

Im Grunde habe ich eine API für www.thetvdb.com in Python geschrieben.Den aktuellen Code finden Sie hier Hier.

Es ruft wie angefordert Daten von der API ab und muss die Daten irgendwie speichern und verfügbar machen, indem es Folgendes tut:

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

Was ist der „beste“ Weg, diese Daten innerhalb der zu abstrahieren? Tvdb() Klasse?

Ich habe ursprünglich eine erweiterte Version verwendet Dict() das automatisch Unterdiktate erstellt hat (so könnten Sie es tun x[1][2][3][4] = "something" ohne es tun zu müssen if x[1].has_key(2): x[1][2] = [] und so weiter)

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

Das funktionierte einwandfrei, aber es gab keine einfache Möglichkeit, dies zu überprüfen x[3][24] sollte existieren oder nicht (daher konnte ich die Ausnahme „season_not_found“ nicht auslösen).

Derzeit werden vier Klassen verwendet: ShowContainer, Show, Season Und Episode.Bei jedem einzelnen handelt es sich um ein sehr einfaches Diktat, dem ich problemlos zusätzliche Funktionen hinzufügen kann (die search() Funktion eingeschaltet Show() Zum Beispiel).Jeder hat eine __setitem__, __getitem_ Und has_key.

Das funktioniert größtenteils gut. Ich kann in „Shows“ nachsehen, ob diese Staffel enthalten ist self.data diktieren, wenn nicht, raise season_not_found.Ich kann auch einchecken Season() ob es diese Episode gibt und so weiter.

Das Problem besteht jetzt darin, dass es sich als Diktat darstellt, aber nicht über alle Funktionen verfügt, und weil ich das überschreibe __getitem__ Und __setitem__ Funktionen kann es leicht passieren, dass sie versehentlich rekursiv aufgerufen werden __getitem__ (Daher bin ich mir nicht sicher, ob ich das verlängern soll Dict Klasse wird Probleme verursachen).

Das andere kleine Problem besteht darin, dass das Hinzufügen von Daten zum Diktat viel aufwändiger ist als beim alten Dict Methode (die war self.data[seas_no][ep_no]['attribute'] = 'something').Sehen _setItem Und _setData.Es ist nicht so schlimm, da es sich derzeit nur um eine schreibgeschützte API-Schnittstelle handelt (die Benutzer der API sollten also immer nur Daten abrufen und keine weiteren hinzufügen), aber es ist kaum ...Elegant.

Ich denke, das Klassenreihensystem ist wahrscheinlich der beste Weg, aber hat jemand eine bessere Idee zum Speichern der Daten?Und würde die verlängern ShowContainer/etc-Klassen mit Dict Probleme verursachen?

War es hilfreich?

Lösung

OK, was Sie brauchen ist classobj aus neuem Modul.Das würde es Ihnen ermöglichen, Ausnahmeklassen dynamisch zu erstellen (classobj nimmt einen String als Argument für den Klassennamen).

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

das gibt dir:

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

Denken Sie daran, dass Sie den Klassennamen immer wie folgt erhalten können:

self.__class__.__name__

Nach einigem Verstümmeln und Verketten von Zeichenfolgen sollten Sie also in der Lage sein, den entsprechenden Ausnahmeklassennamen zu erhalten, ein Klassenobjekt mit diesem Namen zu erstellen und dann diese Ausnahme auszulösen.

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

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

Andere Tipps

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


Wenn Sie SQLite nicht verwenden möchten, können Sie ein Array von Diktaten erstellen.

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 Sie jedem Datensatz Metadaten hinzufügen und ihn ganz einfach durchsuchen

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'])

Ich habe in der Vergangenheit etwas Ähnliches gemacht und ein speicherinternes XML-Dokument als schnelle und schmutzige hierarchische Datenbank zur Speicherung verwendet.Sie können jede Sendung/Staffel/Episode als Element (entsprechend verschachtelt) und die Attribute dieser Dinge als XML-Attribute für die Elemente speichern.Dann können Sie XQuery verwenden, um Informationen wieder herauszubekommen.

NOTIZ: Ich bin kein Python-Typ und weiß daher nicht, wie Ihre XML-Unterstützung aussieht.

ANMERKUNG 2: Sie sollten dies profilieren, da es größer und langsamer ist als die Lösung, die Sie bereits haben.Wenn Sie eine große Verarbeitungsmenge durchführen, ist XML wahrscheinlich nicht Ihr Freund.

Ich verstehe diesen Teil hier nicht:

Das hat gut funktioniert, aber es gab keine einfache Möglichkeit zu überprüfen, ob x[3][24] existieren sollte oder nicht (daher konnte ich die Ausnahme „season_not_found“ nicht auslösen).

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 scheint daran das Problem zu sein?

Bartosz/Zur Klarstellung: „Das hat gut funktioniert, aber es gab keine einfache Möglichkeit zu überprüfen, ob x[3][24] existieren sollte oder nicht.“

x['some show'][3][24] würde Staffel 3, Folge 24 von „Some Show“ zurückgeben.Wenn es keine Staffel 3 gab, möchte ich, dass das Pseudo-Dikt tvdb_seasonnotfound auslöst, wenn „irgendeine Show“ nicht existiert, dann tvdb_shownotfound auslösen

Das aktuelle System besteht aus einer Reihe von Klassen mit jeweils a __getitem__ - Schecks vorzeigen 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 eine Menge wiederholten Code zu geben (jede Klasse ist im Grunde gleich, löst aber einen anderen Fehler aus)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top