هنتكلم على وحدة Pickle وهي خاصة بعملية ال serialization -السريلة- او ال pickling -تخليل- واراها لفظ مناسب جدا لأن بيتم تخزين الكائنات فى وسيط ثم استعادتها مرة اخرى كما كانت
العملية هى تحويل القيم -سواء كائنات او هياكل بيانات- الى هيئة format قابلة للتخزين بهدف امكانية اعادة انشاء الكائن مرة اخري فى مكان اخر -ربما جهاز اخر بعد ارسال تمثيل الكائن عبر الشبكة-
المختصر المفيد لوحدة Pickle
مايهمنا من تلك الوحدة الجميلة هو
dump(object, file)
dumps(object) -> string
load(file) -> object
loads(string) -> object
dumps(obj, protocol=None)
def dumps(obj, protocol=None):
file = StringIO()
Pickler(file, protocol).dump(obj)
return file.getvalue()
وهي تقوم بتخزين الكائن فى صورة نص
المقابل لها هو
loadsdef loads(str):
file = StringIO(str)
return Unpickler(file).load()
وهي بعكس السابقة تقوم بإستعادة الكائن من نص
ومثلهما dump, load ولكنهما تعملان على الملفات
def dump(obj, file, protocol=None):
Pickler(file, protocol).dump(obj)
def load(file):
return Unpickler(file).load()
ماهو ال protocol هو يحدد كيفية وهيئة التخزينHIGHEST_PROTOCOL = 2
وهو اكفأ من 0 ( text mode ) و 1 (binary mode ) و 2 هو اعلى بروتوكول متوفر -وهو الأكفء او إذا مررت عدد اقل من الصفر سيتم استخدامه-
راجع
http://www.python.org/dev/peps/pep-0307مثال
>>> import pickle as p ,
>>> obj={'langname':'python', 'version':"2.7", 'author':{'name':'gvr'}}
>>> p.dumps(obj, 0)
"(dp0\nS'version'\np1\nS'2.7'\np2\nsS'langname'\np3\nS'python'\np4\nsS'author'\np5\n(dp6\nS'name'\np7\nS'gvr'\np8\nss."
>>> p.dumps(obj, 1)
'}q\x00(U\x07versionq\x01U\x032.7q\x02U\x08langnameq\x03U\x06pythonq\x04U\x06authorq\x05}q\x06U\x04nameq\x07U\x03gvrq\x08su.'
>>> p.dumps(obj, 2)
'\x80\x02}q\x00(U\x07versionq\x01U\x032.7q\x02U\x08langnameq\x03U\x06pythonq\x04U\x06authorq\x05}q\x06U\x04nameq\x07U\x03gvrq\x08su.'
>>> p.dumps(obj, p.HIGHEST_PROTOCOL)
'\x80\x02}q\x00(U\x07versionq\x01U\x032.7q\x02U\x08langnameq\x03U\x06pythonq\x04U\x06authorq\x05}q\x06U\x04nameq\x07U\x03gvrq\x08su.'
>>> p.dumps(obj, -1)
'\x80\x02}q\x00(U\x07versionq\x01U\x032.7q\x02U\x08langnameq\x03U\x06pythonq\x04U\x06authorq\x05}q\x06U\x04nameq\x07U\x03gvrq\x08su.'
فكما ترى العائد مختلف حسب البروتوكول المستخدم
الآن عملية اعادة انشاء الكائنات بإستخدام loads
>>> s=p.dumps(obj, -1)
>>> s
'\x80\x02}q\x00(U\x07versionq\x01U\x032.7q\x02U\x08langnameq\x03U\x06pythonq\x04U\x06authorq\x05}q\x06U\x04nameq\x07U\x03gvrq\x08su.'
>>> loadedobj=p.loads(s)
>>> loadedobj
{'version': '2.7', 'langname': 'python', 'author': {'name': 'gvr'}}
الآن على سبيل المثال لدينا هذا الصف
>>> class Snake(object):
... def __init__(self, name, color):
... self.name=name
... self.color=color
...
وانشئنا منه كائن
>>> py=Snake("python", "green")
>>> py
<__main__.Snake object at 0xb7788e0c>
نريد ان نخلل الكائن py حتي نستطيع التعامل معه ربما ارسال معلومات ثعباننا الجميل الى جهاز اخر
>>> s=p.dumps(py)
>>> s
"ccopy_reg\n_reconstructor\np0\n(c__main__\nSnake\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'color'\np6\nS'green'\np7\nsS'name'\np8\nS'python'\np9\nsb."
>>>
الآن نريد استعادة الكائن
>>> obj=p.loads(s)
>>> obj
<__main__.Snake object at 0xb7788eec>
>>> print obj.name, obj.color
python green
طب إذا قائمة من الكائنات ؟
>>> snakes=[Snake("cobra", "black"), Snake("python", "green")]
>>> snakes
[<__main__.Snake object at 0xb7788d6c>, <__main__.Snake object at 0xb7788f4c>]
>>> dumps(snakes)
"(lp0\nccopy_reg\n_reconstructor\np1\n(c__main__\nSnake\np2\nc__builtin__\nobject\np3\nNtp4\nRp5\n(dp6\nS'color'\np7\nS'black'\np8\nsS'name'\np9\nS'cobra'\np10\nsbag1\n(g2\ng3\nNtp11\nRp12\n(dp13\ng7\nS'green'\np14\nsg9\nS'python'\np15\nsba."
>>> sl=p.dumps(snakes)
>>> objs=p.loads(sl)
>>> objs
[<__main__.Snake object at 0xb7788a2c>, <__main__.Snake object at 0xb778c1cc>]
>>>
*اذا استخدامك مقتصر على تلك الدوال الأساسية دون الحاجة لتخصيص ال Pickler او ال Unpickler -صفوف اخرى لم نتحدث عنها فى الوحدة :wub: - فقم بإستخدام الوحدة المحسنة cPickle لأداء افضل
*عند استخدام بروتوكول اكبر من 0 فتأكد من فتح الملفات فى ال binary mode
وبنفس الكيفية load, dump مع الملفات
http://docs.python.org/library/pickle.html