الفرق بين المراجعتين لصفحة: «Python/shelve»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
 
سطر 79: سطر 79:
[[تصنيف:Python]]
[[تصنيف:Python]]
[[تصنيف:Python Modules]]
[[تصنيف:Python Modules]]
[[تصنيف:Python Methods]]

المراجعة الحالية بتاريخ 20:11، 20 سبتمبر 2018


الرف shelf هو كائن مستمر persistent شبيه بالقاموس، ويختلف عن قواعد بيانات "dbm" في أنّ القيم (وليست المفاتيح) في الرفّ يمكن أن تكون من أيّ نوع من أنواع بيانات بايثون، وبمعنى أدق أيّ نوع يمكن لوحدة pickle أن تتعامل معه، وهذا يتضمّن معظم نسخ الأصناف، وأنواع البيانات التعاودية، والكائنات التي تتضمن الكثير من الكائنات الفرعية المشتركة. تكون المفاتيح في الرفوف سلاسل نصية عادية.

تحذير: نظرًا لاستناد الرفوف على وحدة pickle، فإنّ من الخطر أن تحمّل رفًّا من مصادر غير موثوقة. وكما هو الحال مع وحدة pickle، يمكن لعملية تحميل الرفّ أن تنفّذ أيّ نوع من الشيفرات.

دوال الوحدة shelve

تقدّم وحدة shelve دالة واحدة فقط:

الدالة shelve.open()‎

تفتح الدالة قاموسًا مستمرًّا (رفًّا).

تدعم كائنات Shelf جميع التوابع التي تدعمها القواميس، وهذا يسهّل الانتقال من الشيفرات المبنية على القواميس إلى الشيفرات التي تتطلب تخزين البيانات بصورة مستمرة، وتدعم إلى جانب ذلك تابعين إضافيين هما:

sync()‎

يعيد التابع كتابة جميع المدخلات في الذاكرة المخبيئة إذا فُتح الرفّ مع إعطاء المعامل writeback القيمة True. يفرّغ هذا التابع كذلك الذاكرة المخبئية ويزامن القاموس المستمر على القرص الصلب إن كان ذلك ممكنًا. يستدعى هذا التابع تلقائيًا عند إغلاق الرفّ بواسطة الدالة close()‎.

close()‎

يزامن التابع ويغلق كائن dict المستمر. يؤدي إجراء أي عملية على كائن Shelf مغلق إلى إطلاق الخطأ ValueError.

القيود

  • يعتمد اختيار حزمة قاعدة البيانات (مثل dbm.ndbm أو dbm.gnu) على الواجهة البرمجية المتوفّرة؛ ولهذا ليس من الآمن فتح قاعدة البيانات باستخدام dbm مباشرة. تكون قاعدة البيانات كذلك عرضة لمحدّدات dbm في حال استخدامها، وهذا يعني أنّه يجب أن تكون الكائنات (والتمثيل المسلسل لها) ذا حجم صغيرٍ نسبيًا، وفي بعض الحالات النادرة يؤدي التضارب بين المفاتيح إلى رفض قاعدة البيانات لتحديث البيانات.
  • لا تدعم وحدة shelve عمليات الكتابة والقراءة المتزامنة في الكائنات المرفوفة shelved objects. (عمليات القراءة المتعددة والمتزامنة أكثر أمانًا). عندما يفتح برنامج رفًّا للكتابة، يجب أن لا يفتح أي برنامج آخر ذلك الرفّ للقراءة أو للكتابة. يمكن استخدام خاصية قفل الملفات في يونكس لحل هذه المشكلة، ولكنّ هذه التقنية متفاوتة بين إصدارات يونكس وتتطلب معرفة الأداة المستخدمة للتعامل مع قاعدة البيانات.

أصناف الوحدة shelve

الصنف shelve.Shelf

صنف متفرّع من الصنف collections.abc.MutableMapping مهمّته تخزين القيم المسلسلة في كائن dict المعطى.

الصنف shelve.BsdDbShelf

صنف متفرّع من الصنف Shelf ويقدّم التوابع first()‎ و next()‎ و previous()‎ و last()‎ و set_location()‎ وهي متوفّرة في الوحدة bsddb من pybsddb ولكن ليس في وحدات قواعد البيانات الأخرى.

الصنف shelve.DbfilenameShelf

صنف متفرّع من الصنف Shelf ويأخذ ملفًّا عوضًا عن كائن شبيه بالقاموس.

أمثلة

يوضّح المثال التالي الواجهة البرمجية لهذه الوحدة (المفتاح سلسلة نصية، والبيانات كائنات متنوعة):

import shelve

d = shelve.open(filename)  # فتح الرف - يمكن لاسم الملف أن يأخذ لاحقة بواسطة مكتبات
                           # المستوى الواطئ

d[key] = data              # تخزين البيانات في المفتاح (تمسح البيانات القديمة
                           # في حال استخدام مفتاح موجود أصلًا).
data = d[key]              # استراجع نسخة من البيانات الموجودة في المفتاح
                           # يطلق الاستثناء KeyError في حال عدم وجود المفتاح
del d[key]                 # حذف البيانات الموجودة في المفتاح
                           # يطلق الاستثناء KeyError في حال عدم وجود المفتاح

flag = key in d            # العبارة صحيحة إن كان المفتاح موجودًا
klist = list(d.keys())     # قائمة بجميع المفاتيح الموجودة (عملية بطيئة!)‏

# يجب الانتباه إلى ما يلي إذا كان d مفتوحًا دون writeback=True

d['xx'] = [0, 1, 2]        # تعمل هذه الشيفرة كما هو متوقع
d['xx'].append(3)          # *ولكن هذه لا* -- d['xx']‎ مازالت [0, 1, 2]‏!

# في حال عدم استخدام writeback=True يجب كتابة الشيفرة بحذر:
temp = d['xx']             # استخراج النسخة
temp.append(5)             # تعديل النسخة
d['xx'] = temp             # تخزين النسخة من جديد لجعلها مستمرة

# أو يمكن استخدام d=shelve.open(filename,writeback=True)‎ والتي تسمح باستخدام الشيفرة
# d['xx'].append(5) وستعمل كما هو متوقع، ولكنّها قد تستهلك المزيد من الذاكرة
# وتصبح عملية إغلاق الكائن أبطأ.

d.close()                  # إغلاق الكائن

انظر أيضًا

مصادر

صفحة Python object persistence في توثيق بايثون الرسمي.