시즌/쇼/에피소드 데이터를 추상화하는 가장 좋은 방법
-
08-06-2019 - |
문제
기본적으로 저는 www.thetvdb.com에 Python으로 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 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 예외를 발생시킬 수 없었습니다).
현재 4개의 클래스를 사용하고 있습니다. ShowContainer
, Show
, Season
그리고 Episode
.각각은 매우 기본적인 사전이며, 여기에 추가 기능을 쉽게 추가할 수 있습니다( search()
기능 켜짐 Show()
예를 들어).각각은 __setitem__
, __getitem_
그리고 has_key
.
대부분 잘 작동합니다. 프로그램에서 해당 시즌이 있는지 확인할 수 있습니다. self.data
딕셔너리, 그렇지 않다면 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
문제를 일으키나요?
해결책
알겠습니다. 필요한 것은 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")
다른 팁
왜 SQLite를 사용하지 않습니까?Python에는 훌륭한 지원이 있으며 SQL 쿼리를 작성하여 데이터를 가져올 수 있습니다.다음은 Python 문서입니다. SQLite3
SQLite를 사용하고 싶지 않다면 dict 배열을 사용할 수 있습니다.
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이 친구가 되지 않을 것입니다.
여기서는 이 부분을 알 수 없습니다.
이것은 괜찮게 작동했지만 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
그게 무슨 문제인 것 같나요?
Bartosz/"이것은 문제 없이 작동했지만 x[3][24]가 존재해야 하는지 여부를 쉽게 확인할 수 있는 방법이 없었습니다."
x['some show'][3][24]
"Some Show"의 시즌 3, 에피소드 24가 반환됩니다.시즌 3이 없다면 의사 사전에서 tvdb_seasonnotfound를 발생시키고, "일부 쇼"가 존재하지 않으면 tvdb_shownotfound를 발생시키길 원합니다.
일련의 클래스로 구성된 현재 시스템은 각각 __getitem__
- 수표 표시 if self.seasons.has_key(requested_season_number)
, Season 클래스 확인 if self.episodes.has_key(requested_episode_number)
등등.
작동하지만 반복되는 코드가 많은 것 같습니다. (각 클래스는 기본적으로 동일하지만 다른 오류가 발생합니다.)