提取季节/节目/情节数据的最佳方法
基本上,我已经使用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")