最佳的抽象季节/节目/集数数据的方法

17

基本上,我用Python编写了一个API来访问www.thetvdb.com。当前的代码可以在这里找到。

它按需从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 异常)。目前它使用了四个类:ShowContainerShowSeasonEpisode。每个都是一个非常基本的字典,在其中可以轻松添加额外的功能(例如 Show() 上的 search() 函数)。每个字典都有一个 __setitem____getitem_has_key。这在大多数情况下都可以很好地工作,我可以在 Show 中检查是否在其 self.data 字典中具有该季节,如果没有,则引发 season_not_found 异常。我还可以在 Season() 中检查是否有该集,等等。现在的问题是,它表现得像一个字典,但没有所有的功能,并且因为我覆盖了 __getitem____setitem__ 函数,所以很容易意外地递归调用 __getitem__(因此我不确定扩展 Dict 类是否会导致问题)。另一个小问题是将数据添加到字典中比旧的 Dict 方法需要更多的工作(它是 self.data[seas_no][ep_no]['attribute'] = 'something')。看看 _setItem_setData。这也不是很糟糕,因为它目前只是一个只读的 API 接口(因此 API 的用户只能检索数据,而不是添加更多),但它几乎不... 优雅。我认为类系列系统可能是最好的方式,但是否有更好的存储数据的方法?扩展 ShowContainer 等类与 Dict 会导致问题吗?
5个回答

7

好的,你需要的是来自新模块的 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__

因此,在进行一些字符串操作和连接后,您应该能够获得适当的异常类名称,并使用该名称构造一个类对象,然后引发该异常。

附注:您也可以引发字符串,但这已过时。

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

4

为什么不使用SQLite?Python有很好的支持,您可以编写SQL查询来获取数据。这里是sqlite3的Python文档。


如果您不想使用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'])

0

我不太理解这里的部分:

这个方法可以正常工作,但是没有简单的方法来检查 x[3][24] 是否应该存在(所以我无法引发 season_not_found 异常)

有一种方法可以做到 - 叫做 in

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

那似乎有什么问题?


0

我以前做过类似的事情,使用内存中的XML文档作为快速而简单的分层数据库进行存储。您可以将每个节目/季节/剧集存储为元素(适当嵌套),并将这些元素的属性作为xml属性存储在元素上。然后,您可以使用XQuery来获取信息。

注意:我不是Python专家,因此不知道您的xml支持情况如何。

注意2:您需要对其进行分析,因为它比您已经拥有的解决方案更大且更慢。如果您正在进行一些高容量处理,则XML可能不会成为您的朋友。


0

Bartosz/澄清"This worked okay, but there was no easy way of checking if x[3][24] was supposed to exist or not"

x['some show'][3][24]将返回"some show"的第3季第24集。如果没有第3季,我希望伪字典引发tvdb_seasonnotfound错误;如果"some show"不存在,则引发tvdb_shownotfound错误。

当前系统由一系列类组成,每个类都有一个__getitem__ - Show检查if self.seasons.has_key(requested_season_number),Season类检查if self.episodes.has_key(requested_episode_number)等等。

它可以工作,但似乎有很多重复的代码(每个类基本上相同,但引发不同的错误)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接