Лучший способ абстрагировать данные сезона / шоу / эпизода - PullRequest
14 голосов
/ 08 августа 2008

По сути, я написал 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.

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

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

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

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

Ответы [ 5 ]

5 голосов
/ 14 августа 2008

ОК, вам нужно 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__

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

P.S. - Вы также можете поднять строки, но это устарело.

raise(self.__class__.__name__+"Exception")
3 голосов
/ 08 августа 2008

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


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

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'])
0 голосов
/ 12 августа 2008

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 голосов
/ 12 августа 2008

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

Это сработало нормально, но не было простого способа проверить, существует ли 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 голосов
/ 09 августа 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...