Лучший способ абстрагировать данные сезона / шоу / эпизода

По сути, я написал API для www.thetvdb.com на Python. Текущий код можно найти здесь .

Он получает данные из API в соответствии с запросом, должен каким-то образом хранить данные и сделать их доступными, выполнив:

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

Каков «лучший» способ абстрагировать эти данные в Tvdb()классе?

Первоначально я использовал расширенный, Dict()который автоматически создавал поддикты (так что вы можете обойтись x[1][2][3][4] = "something"без необходимости делать if x[1].has_key(2): x[1][2] = []и так далее)

Затем я просто сохранил данные, выполнив self.data[show_id][season_number][episode_number][attribute_name] = "something"

Это работало хорошо, но не было простого способа проверить, x[3][24]должен ли он существовать или нет (поэтому я не смог вызвать исключение season_not_found).

В настоящее время она использует четыре класса: ShowContainer, Show, Seasonи Episode. Каждый из них - очень простой диктат, в который я легко могу добавить дополнительную функциональность ( например, search()функция Show()). В каждом номере есть __setitem__, __getitem_и has_key.

Это работает в основном хорошо, я могу проверить в шоу, если он имеет этот сезон в его self.dataголосе, если нет raise season_not_found. Я также могу проверить, Season()есть ли этот эпизод и так далее.

Проблема теперь он представляет себя как Dict, но не все функциональные возможности , а потому , что я переопределение __getitem__и __setitem__функции, это легко случайно рекурсивный вызов __getitem__(так что я не уверен , что расширение Dictкласса вызывает проблемы ).

Другая небольшая проблема - добавление данных в dict - намного больше работы, чем старый Dictметод (который был self.data[seas_no][ep_no]['attribute'] = 'something'). Смотрите _setItemи _setData. Это не так уж плохо, поскольку в настоящее время это только API-интерфейс только для чтения (поэтому пользователям API следует только извлекать данные, а не добавлять больше), но это вряд ли ... Элегантно.

Я думаю, что система серий классов, вероятно, является лучшим способом, но у кого-нибудь есть лучшая идея для хранения данных? И будет ли расширение ShowContainerклассов / etc Dictпричиной проблем?

8.08.2008 14:05:45
5 ОТВЕТОВ
РЕШЕНИЕ

Хорошо, что вам нужно classobjот нового модуля. Это позволит вам динамически создавать классы исключений ( classobjпринимает строку в качестве аргумента для имени класса).

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

это дает вам:

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

помните, что вы всегда можете получить имя класса через:

self.__class__.__name__

Таким образом, после некоторого искажения и объединения строк вы сможете получить соответствующее имя класса исключения и создать объект класса, используя это имя, а затем вызвать это исключение.

PS - вы также можете поднять строки, но это не рекомендуется.

raise(self.__class__.__name__+"Exception")
6
29.10.2012 20:55:28

Почему бы не использовать SQLite? В Python есть хорошая поддержка, и вы можете писать SQL-запросы для вывода данных. Вот документы Python для sqlite3


Если вы не хотите использовать SQLite, вы можете сделать массив диктов.

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

Таким образом, вы добавляете метаданные в любую запись и очень легко ее ищите

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'])
3
8.08.2008 16:53:10

В прошлом я делал нечто подобное и использовал XML-документ в памяти как быструю и грязную иерархическую базу данных для хранения. Вы можете сохранить каждое шоу / сезон / эпизод как элемент (вложенный соответствующим образом), а атрибуты этих вещей - как атрибуты xml на элементах. Затем вы можете использовать XQuery, чтобы получить информацию обратно.

ПРИМЕЧАНИЕ: я не парень Python, поэтому я не знаю, на что похожа ваша поддержка XML.

ПРИМЕЧАНИЕ 2: Вы захотите профилировать это, потому что оно будет больше и медленнее, чем решение, которое вы уже получили. Вполне вероятно, что если вы выполняете обработку большого объема, то XML, вероятно, не станет вашим другом.

0
9.08.2008 15:13:14

Я не получаю эту часть здесь:

Это работало хорошо, но не было простого способа проверить, существует ли x [3] [24] или нет (поэтому я не смог вызвать исключение season_not_found)

Существует способ сделать это - называется в :

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

в чем проблема?

0
11.08.2008 20:07:59

Bartosz / Чтобы уточнить "Это работало хорошо, но не было простого способа проверить, существует ли x [3] [24] или нет"

x['some show'][3][24]вернется 3 сезон, эпизод 24 "некоторые шоу". Если не было 3 сезона, я хочу, чтобы псевдо-диктат поднял tvdb_seasonnotfound, если «какого-то шоу» не существует, то поднимите tvdb_shownotfound

Текущая система из серии классов, каждый из которых имеет __getitem__- Показать проверки if self.seasons.has_key(requested_season_number), проверки класса Season if self.episodes.has_key(requested_episode_number)и так далее.

Это работает, но, похоже, повторяется много кода (каждый класс в основном один и тот же, но вызывает разные ошибки)

0
13.08.2008 13:43:48