Melhor maneira de temporada dados mostram episódio abstrato / /

votos
13

Basicamente, eu escrevi uma API para www.thetvdb.com em Python. O código atual pode ser encontrada aqui .

Ele agarra dados da API, conforme solicitado, e tem para armazenar os dados de alguma forma, e disponibilizá-lo fazendo:

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

O que é o melhor maneira de abstrair esses dados dentro da Tvdb()classe?

Eu originalmente usado um estendida Dict()que criaram automaticamente sub-dicts (assim você poderia fazer x[1][2][3][4] = somethingsem ter que fazer if x[1].has_key(2): x[1][2] = []e assim por diante)

Então eu apenas armazenados os dados, fazendo self.data[show_id][season_number][episode_number][attribute_name] = something

Isso funcionou bem, mas não havia nenhuma maneira fácil de verificar se x[3][24]era suposto existir ou não (então eu não podia levantar a exceção season_not_found).

Atualmente ele está usando quatro classes: ShowContainer, Show, Seasone Episode. Cada um é um dicionário muito básico, que pode facilmente adicionar funcionalidade extra no (a search()função de Show(), por exemplo). Cada um tem um __setitem__, __getitem_e has_key.

Isso funciona principalmente excelentes, posso check-in Shows se ele tem essa temporada nele de self.datadict, se não, raise season_not_found. Eu também pode verificar Season()se ele tem esse episódio e assim por diante.

O problema agora é que está apresentando-se como um dicionário, mas não tem toda a funcionalidade, e porque eu estou substituindo as __getitem__e __setitem__funções, é fácil ligar acidentalmente recursivamente __getitem__(então eu não tenho certeza se estender a Dictclasse irá causar problemas ).

O outro pequeno problema é a adição de dados no dict é muito mais trabalho do que o antigo Dictmétodo (que era self.data[seas_no][ep_no]['attribute'] = 'something'). Ver _setIteme _setData. Não é muito ruim, já que é atualmente apenas um só de leitura interface API (de modo que os usuários da API só deve recuperar dados, não adicionar mais), mas é quase ... elegante.

Eu acho que o sistema da série-de-classes é provavelmente a melhor maneira, mas alguém tem uma idéia melhor para armazenar os dados? E iria estender as ShowContaineraulas / etc com Dictcausar problemas?

Publicado 08/08/2008 em 15:05
fonte usuário
Em outras línguas...                            


5 respostas

votos
5

OK, o que você precisa é classobjde novo módulo. Que lhe permitiria construir classes de exceção dinamicamente ( classobjrecebe uma string como um argumento para o nome da classe).

import new
myexc=new.classobj("ExcName",(Exception,),{})
i=myexc("This is the exc msg!")
raise i

isto dá-lhe:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
__main__.ExcName: This is the exc msg!

lembre-se que você sempre pode obter o nome da classe, através de:

self.__class__.__name__

Então, depois de algum mangling corda e concatenação, você deve ser capaz de obter o nome da classe de exceção apropriado e construir um objeto da classe usando esse nome e, em seguida, levantar essa exceção.

PS - você também pode aumentar cordas, mas isso é obsoleto.

raise(self.__class__.__name__+"Exception")
Respondeu 14/08/2008 em 08:08
fonte usuário

votos
3

Por que não usar SQLite? Há um bom suporte em Python e você pode escrever consultas SQL para obter os dados. Aqui está a documentação Python para sqlite3


Se você não quiser usar SQLite você poderia fazer uma série de dicts.

episodes = []
episodes.append({'season':1, 'episode': 2, 'name':'Something'})
episodes.append({'season':1, 'episode': 2, 'name':'Something', 'actors':['Billy Bob', 'Sean Penn']})

Dessa forma, você adicionar metadados a qualquer registro e busca-lo com muita facilidade

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'])
Respondeu 08/08/2008 em 17:45
fonte usuário

votos
0

Bartosz / Para esclarecer "Isso funcionou bem, mas não havia nenhuma maneira fácil de verificar se x [3] [24] deveria existir ou não"

x['some show'][3][24]retornaria 3 ª temporada, episódio 24 de "algum show." Se não houvesse a 3 ª temporada, eu quero que o pseudo-dict para levantar tvdb_seasonnotfound, se "algum programa" não existe, em seguida, levantar tvdb_shownotfound

O actual sistema de uma série de classes, cada um com um __getitem__- Mostrar cheques if self.seasons.has_key(requested_season_number), as verificações de classe temporada if self.episodes.has_key(requested_episode_number)e assim por diante.

Ele funciona, mas parece haver um monte de código repetido (cada classe é basicamente o mesmo, mas levanta um erro diferente)

Respondeu 12/08/2008 em 18:55
fonte usuário

votos
0

Eu não entendo essa parte aqui:

Isso funcionou bem, mas não havia nenhuma maneira fácil de verificar se x [3] [24] deveria existir ou não (então eu não podia levantar a exceção season_not_found)

Há uma maneira de fazê-lo - chamado em :

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

o que parece ser o problema com isso?

Respondeu 11/08/2008 em 21:07
fonte usuário

votos
0

Eu tenho feito algo semelhante no passado e utilizado um documento XML na memória como um banco de dados rápido e sujo hierachical para armazenamento. Você pode armazenar cada show / época / episódio como um elemento (aninhados apropriadamente) e atributos dessas coisas como atributos XML nos elementos. Então você pode usar XQuery para obter informações de volta para fora.

NOTA: Eu não sou um cara de Python, então eu não sei o seu apoio xml é como.

NOTA 2: Você vai querer perfil isto porque ele vai ser maior e mais lento do que a solução que você já tem. Provavelmente o suficiente se você estiver fazendo algum processamento de alto volume, em seguida, XML provavelmente não vai ser seu amigo.

Respondeu 09/08/2008 em 16:13
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more