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

StackOverflow https://stackoverflow.com/questions/5966

  •  08-06-2019
  •  | 
  •  

Вопрос

По сути, я написал 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.Каждый из них представляет собой очень простой диктант, в который я могу легко добавить дополнительную функциональность (the 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__

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

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

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

Другие советы

Почему бы не использовать 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'])

Я делал нечто подобное в прошлом и использовал 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

в чем, по-видимому, проблема с этим?

Бартош / Пояснить: "Это сработало нормально, но не было простого способа проверить, должен ли x [3] [24] существовать или нет".

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top