Разница между травлением объекта по кусочкам против всего сразу? - PullRequest
0 голосов
/ 16 декабря 2018

Учитывая произвольный питонический объект, подобный этому:

class ExampleObj(object):
    def __init__(self):
        self.a = 'a'
        self.b = 'b'
        self.c = 'c'

obj = ExampleObj()

Есть ли функциональная разница между этими двумя подходами сериализации?

Кусочное травление

base = type(obj)
name = obj.__class__.__name__
pickled_data = {}

for key,val in obj.__dict__.items():
    pickled_data[key] = pickle.dumps(val)

vars = {k : pickle.loads(v) for k,v in pickled_data.items()}
restored = type(name, (base,), vars)

Стандартное травление

restored = pickle.loads( pickle.dumps(obj) )

Я не могу себе это представить, но я боюсь, что может быть какой-то крайний случай, который я не рассматриваю.

(В моем приложении некоторые объекты могут не иметь сериализуемых переменных. Мы надеялись реализовать кусочное травление, поэтому мы лучше определим, какие переменные мешают нам производить травление объекта) *

1 Ответ

0 голосов
/ 16 декабря 2018

В первом случае вы создаете экземпляр type, тогда как во втором случае вы создаете экземпляр типа ExampleObj.Чтобы увидеть, как эти два результата функционально различны, я назову restored_1 результат вашего первого примера, а restored_2 второй.

type(restored_1)  # type
type(restored_2)  # __main__.ExampleObj

Таким образом, restored_1 и restored_2 будутне быть функционально эквивалентным в том смысле, в котором вы упоминаете, что ищете.

В качестве простой иллюстрации добавьте метод или свойство к ExampleObj и попробуйте использовать восстановленный объект из любой процедуры различными способами.

class ExampleObj(object):
    def __init__(self):
        self.a = 'a'
        self.b = 'b'
        self.c = 'c'

    def foo(self):
        print('bar')

    @property
    def baz(self):
        print(self.a + self.b)

obj = ExampleObj()

После выполнения вашего первого кода, который возвращает экземпляр type:

restored_1.foo()     # exception raised because restored_1 is not an ExampleObj instance
restored_1.bar       # returns <property at 0x107863138> type
restored_1.__dict__  # returns a mappingproxy object

После выполнения вашего второго кода, который возвращает экземпляр ExampleObj:

restored_2.foo()     # bar
restored_2.bar       # ab
restored_2.__dict__  # {'a': 'a', 'b': 'b', 'c': 'c'}

Если вы ищете обсуждение подходов, чтобы выяснить, для какого экземпляра атрибутов привязки экземпляра произошел сбой, посмотрите этот вопрос: Как определить, для какого атрибута атрибута объекта сбой происходит сбой?

...