Question

Fondamentalement, j'ai écrit une API sur www.thetvdb.com en Python.Le code actuel peut être trouvé ici.

Il récupère les données de l'API comme demandé, et doit stocker les données d'une manière ou d'une autre et les rendre disponibles en faisant :

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

Quelle est la « meilleure » ​​façon d’extraire ces données dans le Tvdb() classe?

À l'origine, j'utilisais une version étendue Dict() qui créait automatiquement des sous-dicts (vous pouvez donc faire x[1][2][3][4] = "something" sans avoir à faire if x[1].has_key(2): x[1][2] = [] et ainsi de suite)

Ensuite, j'ai juste stocké les données en faisant self.data[show_id][season_number][episode_number][attribute_name] = "something"

Cela fonctionnait bien, mais il n'y avait pas de moyen simple de vérifier si x[3][24] était censé exister ou non (je n'ai donc pas pu déclencher l'exception season_not_found).

Actuellement, il utilise quatre classes : ShowContainer, Show, Season et Episode.Chacun est un dictionnaire très basique, auquel je peux facilement ajouter des fonctionnalités supplémentaires (le search() fonction sur Show() Par exemple).Chacun a un __setitem__, __getitem_ et has_key.

Cela fonctionne généralement bien, je peux vérifier dans les émissions si cette saison est disponible. self.data dict, sinon, raise season_not_found.Je peux également m'enregistrer Season() s'il a cet épisode et ainsi de suite.

Le problème maintenant est qu'il se présente comme un dict, mais n'a pas toutes les fonctionnalités, et parce que j'écrase le __getitem__ et __setitem__ fonctions, il est facile d'appeler accidentellement de manière récursive __getitem__ (donc je ne suis pas sûr de prolonger le Dict la classe posera des problèmes).

L'autre léger problème est que l'ajout de données dans le dict demande beaucoup plus de travail que l'ancien. Dict méthode (qui était self.data[seas_no][ep_no]['attribute'] = 'something').Voir _setItem et _setData.Ce n'est pas trop mal, puisqu'il ne s'agit actuellement que d'une interface API en lecture seule (les utilisateurs de l'API ne doivent donc récupérer que des données, pas en ajouter), mais ce n'est guère le cas...Élégant.

Je pense que le système de séries de classes est probablement le meilleur moyen, mais quelqu'un a-t-il une meilleure idée pour stocker les données ?Et prolongerait-il le ShowContainer/etc classes avec Dict causer des problèmes?

Était-ce utile?

La solution

OK, ce dont tu as besoin c'est classobj du nouveau module.Cela vous permettrait de construire dynamiquement des classes d'exception (classobj prend une chaîne comme argument pour le nom de la classe).

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

cela vous donne :

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

rappelez-vous que vous pouvez toujours obtenir le nom de la classe via :

self.__class__.__name__

Ainsi, après quelques modifications et concaténation de chaînes, vous devriez être en mesure d'obtenir le nom de classe d'exception approprié et de construire un objet de classe en utilisant ce nom, puis de déclencher cette exception.

P.S.- vous pouvez également augmenter les chaînes, mais cela est obsolète.

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

Autres conseils

Pourquoi ne pas utiliser SQLite ?Il existe un bon support en Python et vous pouvez écrire des requêtes SQL pour extraire les données.Voici la documentation Python pour sqlite3


Si vous ne souhaitez pas utiliser SQLite, vous pouvez créer un tableau de dictionnaires.

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

De cette façon, vous ajoutez des métadonnées à n'importe quel enregistrement et effectuez des recherches très facilement.

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

J'ai fait quelque chose de similaire dans le passé et utilisé un document XML en mémoire comme base de données hiérarchique rapide et sale pour le stockage.Vous pouvez stocker chaque émission/saison/épisode en tant qu'élément (imbriqué de manière appropriée) et les attributs de ces éléments en tant qu'attributs XML sur les éléments.Ensuite, vous pouvez utiliser XQuery pour récupérer des informations.

NOTE: Je ne suis pas un gars Python donc je ne sais pas à quoi ressemble votre support XML.

NOTE 2: Vous souhaiterez profiler cela car ce sera plus gros et plus lent que la solution que vous avez déjà.Il est probable que si vous effectuez un traitement à volume élevé, XML ne sera probablement pas votre ami.

Je ne comprends pas cette partie ici :

Cela a bien fonctionné, mais il n'y avait pas de moyen simple de vérifier si x[3][24] était censé exister ou non (je n'ai donc pas pu déclencher l'exception season_not_found)

Il existe un moyen de le faire - appelé dans:

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

quel semble être le problème avec ça ?

Bartosz/Pour clarifier "Cela fonctionnait bien, mais il n'y avait pas de moyen simple de vérifier si x[3][24] était censé exister ou non"

x['some show'][3][24] reviendrait la saison 3, épisode 24 de "some show".S'il n'y a pas eu de saison 3, je veux que le pseudo-dict déclenche tvdb_seasonnotfound, si "une émission" n'existe pas, alors relance tvdb_shownotfound

Le système actuel d'une série de classes, chacune avec un __getitem__ - Afficher les chèques if self.seasons.has_key(requested_season_number), la classe Saison vérifie if self.episodes.has_key(requested_episode_number) et ainsi de suite.

Cela fonctionne, mais il semble y avoir beaucoup de code répété (chaque classe est fondamentalement la même, mais génère une erreur différente)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top