Самостоятельное расщепление в методе класса в Python - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь создать объект, который может сериализовать и десериализовать себя с помощью метода класса, без использования оператора return (я не хочу статический метод).Это концепция моего класса и наивный вариант использования:

import pickle

class A:
    def __init__(self):
        self.x = 0

    def add(self):
        self.x += 1

    def serialize(self, filename):
        """Simple object serialization given a filename"""
        with open(filename, 'wb') as f:
            pickle.dump(self, f)
            print("Serialized with value of: %d" % (self.x))

    def deserialize(self, filename):
        """Simple object deserialization given a filename"""
        with open(filename, 'rb') as f:
            print("self.x before load (inside deserialize): %d" % (self.x))
            self = pickle.load(f)
            print("Deserialized value inside deserialize function: %d" % (self.x))



a1 = A()
a2 = A()

a1.add()
a1.add()

a1.serialize('a.pkl')
a2.deserialize('a.pkl')

print("Deserialized value outside: %d" % (a2.x))

Однако, как только я оставляю метод десериализации, self (в данном случае экземпляр a2) не сохраняет свое значение.

Вывод при запуске:

>> Serialized with value of: 2
>> self.x before load (inside deserialize): 0
>> Deserialized value inside deserialize function: 2
>> Deserialized value outside: 0

Почему это происходит?Я также пытался использовать deepcopy сразу после pickle.load в функции deserialize, но, похоже, ничего не работает, и я хотел бы понять, почему.

Заранее спасибо

1 Ответ

0 голосов
/ 17 октября 2018

Причина, по которой это не работает, заключается в том, что вы не можете назначить себя (или, скорее: делать это не делает то, что вы думаете).Если вам интересно узнать, что на самом деле происходит, попробуйте назначить что-то странное для self, например self = "foobar" (поведение не изменится).


Сделайте deserialize методом класса и используйтеэто как «конструктор»:

@classmethod
def deserialize(cls, filename):
    """Simple object deserialization given a filename"""
    with open(filename, 'rb') as f:
        obj = pickle.load(f)
        print("Deserialized value inside deserialize function: %d" % (obj.x))
        return obj

Затем используйте его так:

a2 = A.deserialize('a.pkl')

Вывод:

Сериализуется со значением:2
Десериализованное значение внутри функции десериализации: 2
Десериализованное значение снаружи: 2

...