По сути, я написал 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
причиной проблем?
Хорошо, что вам нужно 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")
Почему бы не использовать 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'])
В прошлом я делал нечто подобное и использовал XML-документ в памяти как быструю и грязную иерархическую базу данных для хранения. Вы можете сохранить каждое шоу / сезон / эпизод как элемент (вложенный соответствующим образом), а атрибуты этих вещей - как атрибуты xml на элементах. Затем вы можете использовать XQuery, чтобы получить информацию обратно.
ПРИМЕЧАНИЕ: я не парень Python, поэтому я не знаю, на что похожа ваша поддержка XML.
ПРИМЕЧАНИЕ 2: Вы захотите профилировать это, потому что оно будет больше и медленнее, чем решение, которое вы уже получили. Вполне вероятно, что если вы выполняете обработку большого объема, то XML, вероятно, не станет вашим другом.
Я не получаю эту часть здесь:
Это работало хорошо, но не было простого способа проверить, существует ли 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
в чем проблема?
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)
и так далее.
Это работает, но, похоже, повторяется много кода (каждый класс в основном один и тот же, но вызывает разные ошибки)