2015-12-08 3 views
1

Я пытаюсь DeepCopy словарь в Python 3.4, но некоторые из значений не «pickable», то есть, когда я пытаюсь DeepCopy словарь, он вызывает исключение RuntimeErrorкак DeepCopy, когда травление не представляется возможным

*** RuntimeError: Pickling of "DataObject" instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html) 

Что было бы лучшим вариантом для глубокой печати словаря?

До сих пор я рекурсивно перебираю словарь и создаю новый, но я хотел бы знать, есть ли более надежное и элегантное решение.

Примечание: Я не могу изменить структуру DataObject для поддержки травления.

ответ

3

Вы можете добавить функции копирования в copyreg module для обработки типов, которые не могут быть солеными:

import copyreg 

pickle_dataobject(do): 
    return DataObject, (do.arg1, do.arg2) 

copyreg.pickle(DataObject, pickle_dataobject) 

Идея заключается в том, что вы возвращаете конструктор и аргументы, которые должны быть переданы в конструктор, чтобы заново создать первоначальное значение.

copy.deepcopy() функция затем использует выше pickle_dataobject(), чтобы получить копию, когда ob is DataObject верно (класс ищется в словаре copyreg.dispatch_table что copyreg.pickle() добавляет вашу функцию).

+0

Я вижу, что это правильный способ сделать это. К сожалению, в моем случае у меня нет хорошей видимости всех аргументов DataObject. Я работаю с некоторыми «специальными» (раздражающими) интерфейсами swig библиотек C++, которые имеют много таких проблем. Я не вижу, как использовать этот метод, не имея возможности перечислить все аргументы. Это, я думаю, это путь, поэтому я буду отмечать его как правильный ответ. –

+0

@ zom-pro: ну, как вы теперь создаете новые экземпляры? Возможно, это еще один класс, который содержит эти вещи, в которые вам нужно зацепиться? Идея заключается в том, что вы все оставите в 'copy.deepcopy()' все еще, но научите ее копировать конкретные типы, не изменяя эти типы напрямую. Но если эти объекты создаются как внутренние структуры данных для некоторого класса контейнера, научите «copyreg» о классе контейнера. –

+0

с Python 2.7 copy_reg. Модуль copy_reg был переименован в copyreg в Python 3. – shrishinde