Подтвердить что ты не робот

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

В принципе, я написал 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. Каждый из них является очень простым dict, который я могу легко добавить в функциональность (например, search() на Show()). Каждый из них имеет __setitem__, __getitem_ и has_key.

Это работает в основном отлично, я могу проверить шоу, если в нем есть этот сезон self.data dict, если нет, 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 вызвать проблемы?

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

Это сработало хорошо, но не было простого способа проверить, должен ли существовать 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

что с этим связано?

Ответ 5

Bartosz/Чтобы уточнить "Это сработало хорошо, но не было простого способа проверить, должен ли существовать 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) и т.д.

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