أفضل طريقة لتجريد بيانات الموسم/العرض/الحلقة

StackOverflow https://stackoverflow.com/questions/5966

  •  08-06-2019
  •  | 
  •  

سؤال

في الأساس، لقد قمت بكتابة واجهة برمجة التطبيقات إلى 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).

يستخدم حاليًا أربع فئات: ShowContainer, Show, Season و Episode.كل واحدة منها عبارة عن إملاء أساسي للغاية، ويمكنني بسهولة إضافة وظائف إضافية في (ملف search() وظيفة على Show() على سبيل المثال).كل لديه __setitem__, __getitem_ و has_key.

يعمل هذا بشكل جيد في الغالب، يمكنني التحقق من العروض إذا كان بها هذا الموسم self.data ديكت، إذا لم يكن كذلك، raise season_not_found.يمكنني أيضًا تسجيل الوصول Season() إذا كان لديه تلك الحلقة وما إلى ذلك.

المشكلة الآن هي أنها تقدم نفسها كإملاء، ولكنها لا تحتوي على جميع الوظائف، ولأنني أتجاوز __getitem__ و __setitem__ الوظائف، فمن السهل الاتصال بشكل متكرر عن طريق الخطأ __getitem__ (لذلك لست متأكدًا مما إذا كان تمديد Dict الطبقة سوف تسبب مشاكل).

المشكلة البسيطة الأخرى هي أن إضافة البيانات إلى الإملاء يتطلب عملاً أكثر بكثير من القديم Dict الطريقة (التي كانت self.data[seas_no][ep_no]['attribute'] = 'something').يرى _setItem و _setData.إنه ليس سيئًا للغاية، نظرًا لأنه حاليًا مجرد واجهة API للقراءة فقط (لذا يجب على مستخدمي واجهة برمجة التطبيقات استرداد البيانات فقط، وليس إضافة المزيد)، ولكن من الصعب...رائع.

أعتقد أن نظام سلسلة الفئات هو على الأرجح أفضل طريقة، ولكن هل لدى أي شخص فكرة أفضل لتخزين البيانات؟ومن شأنه أن يمتد ShowContainer/ الخ الطبقات مع 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")

نصائح أخرى

لماذا لا تستخدم سكليتي؟يوجد دعم جيد في Python ويمكنك كتابة استعلامات SQL للحصول على البيانات.هنا مستندات بايثون ل sqlite3


إذا كنت لا ترغب في استخدام 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 للحصول على المعلومات مرة أخرى.

ملحوظة: أنا لست من محبي لغة بايثون، لذا لا أعرف شكل دعم 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] سيعود الموسم الثالث الحلقة 24 من برنامج Some Show.إذا لم يكن هناك موسم 3، أريد أن يرفع الإملاء الزائف tvdb_seasonnotfound، إذا لم يكن "بعض العروض" موجودًا، فقم برفع tvdb_shownotfound

النظام الحالي من سلسلة من الطبقات، ولكل منها __getitem__ - إظهار الشيكات if self.seasons.has_key(requested_season_number), ، الشيكات فئة الموسم if self.episodes.has_key(requested_episode_number) وما إلى ذلك وهلم جرا.

إنه يعمل، ولكن يبدو أن هناك الكثير من التعليمات البرمجية المتكررة (كل فئة هي نفسها في الأساس، ولكنها تثير خطأ مختلفًا)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top