ما هو الاستخدام الدقيق لـ __reduce__ في Pickler

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

  •  29-07-2022
  •  | 
  •  

سؤال

أعلم أنه لكي تكون قابلاً للانتقاء ، يجب على الفصل الكتابة فوقها __reduce__ الطريقة ، وعليها إرجاع السلسلة أو tuple.

كيف تعمل هذه الوظيفة؟ ما هو الاستخدام الدقيق ل __reduce__؟ متى سيتم استخدامه؟

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

المحلول

عندما تحاول مخلل كائن ، قد يكون هناك بعض الخصائص التي لا تتسلسل بشكل جيد. مثال واحد على هذا هو مقبض ملف مفتوح. لن يعرف Pickle كيفية التعامل مع الكائن وسوف يرمي خطأ.

يمكنك إخبار وحدة المخلل كيفية التعامل مع هذه الأنواع من الكائنات أصلاً داخل فئة مباشرة. دعونا نرى مثالا على كائن يحتوي على خاصية واحدة ؛ مقبض ملف مفتوح:

import pickle

class Test(object):
    def __init__(self, file_path="test1234567890.txt"):
        # An open file in write mode
        self.some_file_i_have_opened = open(file_path, 'wb')

my_test = Test()
# Now, watch what happens when we try to pickle this object:
pickle.dumps(my_test)

يجب أن تفشل وإعطاء تتبع:

Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  --- snip snip a lot of lines ---
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects

ومع ذلك ، لو حددنا أ __reduce__ الطريقة في لدينا Test الفصل ، كان من المجلس أن يعرف كيفية إجراء تسلسل هذا الكائن:

import pickle

class Test(object):
    def __init__(self, file_path="test1234567890.txt"):
        # Used later in __reduce__
        self._file_name_we_opened = file_path
        # An open file in write mode
        self.some_file_i_have_opened = open(self._file_name_we_opened, 'wb')
    def __reduce__(self):
        # we return a tuple of class_name to call,
        # and optional parameters to pass when re-creating
        return (self.__class__, (self._file_name_we_opened, ))

my_test = Test()
saved_object = pickle.dumps(my_test)
# Just print the representation of the string of the object,
# because it contains newlines.
print(repr(saved_object))

هذا يجب أن يعطيك شيئًا مثل: "c__main__\nTest\np0\n(S'test1234567890.txt'\np1\ntp2\nRp3\n.", ، والتي يمكن استخدامها لإعادة إنشاء الكائن بمقابض الملف المفتوح:

print(vars(pickle.loads(saved_object)))

بشكل عام ، __reduce__ تحتاج الطريقة إلى إرجاع tuple مع عنصرين على الأقل:

  1. فئة كائن فارغة للاتصال. في هذه الحالة، self.__class__
  2. مجموعة من الحجج لتمريرها إلى مُنشئ الفصل. في المثال ، إنها سلسلة واحدة ، وهي المسار إلى الملف لفتحها.

استشر مستندات للحصول على شرح مفصل لما __reduce__ يمكن أن تعود الطريقة.

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