Pregunta

Is it possible to deepcopy a shelve object in Python? When I try to deepcopy it, I get the following error:

import shelve,copy
input = shelve.open("test.dict", writeback=True)
input.update({"key1": 1, "key2": 2})
newinput = copy.deepcopy(input)
>> object.__new__(DB) is not safe, use DB.__new__()

Does it mean shelves are not-copyable?

Edit: Maybe it might be better if I elaborate my problem more: I am keeping a large dictionary as a shelve object, and I want to save the whole shelve object (= all key, val pairs I generated so far) to a seperate file while I keep adding new items to the original dict.

Probably I could first sync the shelve and copy the shelve file on disk explicitly, however I don't like that approach.

¿Fue útil?

Solución 2

You could obtain a shallow copy by dict(input) and deepcopy that. Then maybe create another shelve on a new file and populate it via the update method.

newinput = shelve.open("newtest.dict")
newinput.update(copy.deepcopy(dict(input)))

Otros consejos

No, I don't think they are copiable (unless you monkey patch the class or convert into a dict). Here's why :

copy.copy() and copy.deepcopy() call the __copy__() and __deepcopy__() methods for the instances which does not depend on a "standard" type (which are atomic, list, tuple and instance methods ). If the class does not have those attributes, it falls back to __reduce_ex__ and __reduce__ . (see copy.py in your sources)

Unfortunately, the shelve object Shelf is based on UserDict.DictMixin which does not define copy() (and neither does Shelf) :

class DictMixin:

# Mixin defining all dictionary methods for classes that already have
# a minimum dictionary interface including getitem, setitem, delitem,
# and keys. Without knowledge of the subclass constructor, the mixin
# does not define __init__() or copy().  In addition to the four base
# methods, progressively more efficiency comes with defining
# __contains__(), __iter__(), and iteritems().

It may be a good idea to submit an issue to the shelve module bug tracker.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top