提取季节/节目/情节数据的最佳方法

时间:2020-03-05 18:38:37  来源:igfitidea点击:

基本上,我已经使用Python向www.thetvdb.com编写了API。当前代码可以在这里找到。

它根据请求从API抓取数据,并且必须以某种方式存储数据,并通过执行以下操作使其可用:

print tvdbinstance[1][23]['episodename'] # get the name of episode 23 of season 1

在" Tvdb()"类中提取此数据的"最佳"方法是什么?

我最初使用扩展的Dict()自动创建子字典(因此我们可以执行x [1] [2] [3] [4] =" something"`而不必执行if if [[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和Epsode。每个命令都是非常基本的命令,我可以在其中轻松添加额外的功能(例如Show()上的search()函数)。每个都有一个__setitem__,__getitem_和has_key。

这通常可以正常工作,我可以在Shows的" self.data"字典中检查是否有该季节,如果没有,请" raise season_not_found"。我也可以检查" Season()"是否包含该情节,依此类推。

现在的问题是它以字典的形式呈现,但没有所有功能,并且由于我覆盖了__getitem__和__setitem__函数,因此很容易意外地递归调用__getitem__(所以我不知道扩展Dict类是否会引起问题)。

另一个小问题是,向dict中添加数据比旧的" Dict"方法(" self.data [seas_no] [ep_no] ['attribute"] ='something')的工作量大得多。参见_setItem_setData`。还算不错,因为它目前只是一个只读的API接口(因此,API的用户应该只检索数据,而不能添加更多数据),但是几乎没有。

我认为"类序列"系统可能是最好的方法,但是是否有人对存储数据有更好的主意?并且用Dict扩展ShowContainer/ etc类会引起问题吗?

解决方案

回答

为什么不使用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'])

回答

我过去做过类似的事情,并使用内存中的XML文档作为快速,肮脏的分层数据库进行存储。我们可以将每个节目/季节/剧集存储为一个元素(适当地嵌套),并将这些事物的属性存储为元素上的xml属性。然后,我们可以使用XQuery取回信息。

注意:我不是Python专家,所以我不知道xml支持是什么样的。

注意2:我们需要对此进行分析,因为它会比现有的解决方案更大或者更慢。如果我们要进行大量处理,那么XML可能不会成为朋友。

回答

我在这里没有这部分:

This worked okay, but there was no easy way of checking if x[3][24] was supposed to exist or not (so I couldn't raise the season_not_found exception)

有一种方法可以调用:

>>>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季," some show"的第24集。如果没有第3季,我希望伪指令提高tvdb_seasonnotfound,如果"某些演出"不存在,则提高tvdb_shownotfound

当前一系列类的系统,每个类都有一个__getitem__ Show来检查是否self.seasons.has_key(requested_season_number),Season类检查是否self.episodes.has_key(requested_episode_number),依此类推。

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

回答

好的,我们需要的是新模块中的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")