أفضل طريقة لتخزين واستخدام ملف نص كبير في بيثون

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

  •  03-07-2019
  •  | 
  •  

سؤال

أقوم بإنشاء خادم متصل بالشبكة للحصول على clone boggle كتبته في Python ، والذي يقبل المستخدمين ، ويحل الألواح ، ويسجل إدخال المشغل. ملف القاموس الذي أستخدمه هو 1.8 ميغابايت (قاموس Enable2K) ، وأحتاجه إلى أن يكون متاحًا لعدة فصول حلول الألعاب. في الوقت الحالي ، لديّ حتى يتكرر كل فصل من خلال خط الملف على حدة ويولد جدول التجزئة (صفيف ترابط) ، ولكن كلما زادت فئات Solver I INSTANTING ، كلما زادت الذاكرة.

ما أود القيام به هو استيراد ملف القاموس مرة واحدة ونقله إلى كل مثيل حلال كما هو بحاجة إليه. ولكن ما هي أفضل طريقة للقيام بذلك؟ هل يجب علي استيراد القاموس في الفضاء العالمي ، ثم الوصول إليه في فئة Solver باسم Globals () ['القاموس']؟ أم يجب أن أستورد القاموس ثم تمريره كحجة إلى مُنشئ الفصل؟ هل واحدة من هذه أفضل من الآخر؟ هل هناك خيار ثالث؟

هل كانت مفيدة؟

المحلول

إذا قمت بإنشاء وحدة Dictionary.py ، التي تحتوي على رمز يقرأ الملف وينشئ قاموسًا ، سيتم تنفيذ هذا الرمز فقط في المرة الأولى التي يتم استيرادها. ستعيد المزيد من الواردات إشارة إلى مثيل الوحدة النمطية الحالية. على هذا النحو ، يمكن لفصولك:

import dictionary

dictionary.words[whatever]

حيث القاموس. بيبي:

words = {}

# read file and add to 'words'

نصائح أخرى

على الرغم من أنها في الأساس منفردة في هذه المرحلة ، تنطبق الحجج المعتادة ضد Globals. للحصول على كائن Singleton-Substuton ، ابحث عن كائن "Borg".

هذا هو حقا الفرق الوحيد. بمجرد إنشاء كائن القاموس ، فإنك تربط مراجع جديدة فقط أثناء مرورها إلا إذا قمت بإجراء نسخة عميقة بشكل صريح. من المنطقي أن يتم بناؤه مركزيًا مرة واحدة وفقط طالما لا يتطلب كل مثيل حلال نسخة خاصة للتعديل.

آدم ، تذكر أنه في بيثون عندما تقول:

a = read_dict_from_file()
b = a

... أنت لست في الواقع نسخ a, ، وبالتالي باستخدام المزيد من الذاكرة ، فأنت تصنع فقط b إشارة أخرى إلى نفس الكائن.

لذلك في الأساس أي من الحلول التي تقترحها ستكون أفضل بكثير من حيث استخدام الذاكرة. في الأساس ، اقرأ في القاموس ذات مرة ثم انتظر إلى إشارة إلى ذلك. سواء كنت تفعل ذلك بمتغير عالمي ، أو تم نقله إلى كل مثيل ، أو أي شيء آخر ، فسوف تشير إلى نفس الكائن ولا تكرره.

أي واحد هو الأكثر بيثونيا؟ هذا كله علبة من الديدان ، لكن هذا ما سأفعله شخصيًا:

def main(args):
  run_initialization_stuff()
  dictionary = read_dictionary_from_file()
  solvers = [ Solver(class=x, dictionary=dictionary) for x in len(number_of_solvers) ]

HTH.

اعتمادًا على ما يحتويه مقالك ، قد تكون مهتمًا بوحدات "الرف" أو "أند بي إم". إنها تعطيك واجهات تشبه القولون (مجرد سلاسل كمفاتيح وعناصر لـ "anydbm" ، والسلاسل كمفاتيح وأي كائن بيثون كعنصر لـ "الرفى") ولكن البيانات موجودة بالفعل في ملف DBM (GDBM ، NDBM ، DBHASH ، BSDDB ، اعتمادًا على ما هو متاح على النظام الأساسي.) ربما لا تزال ترغب في مشاركة قاعدة البيانات الفعلية بين الفئات كما تطلب ، ولكنها ستتجنب خطوة التحليل النص بت الدم.

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