What exactly is the relationship between pickle and copy.deepcopy? What mechanisms do they share, and how?
It is clear the two ar
Ok, I had to read the source code for this one, but it looks like it's a pretty simple answer. http://svn.python.org/projects/python/trunk/Lib/copy.py
copy looks up some of the builtin types it knows what the constructors look like for (registered in the _copy_dispatch dictionary, and when it doesn't know how to copy the basic type, it imports copy_reg.dispatch_table... which is the place where pickle registers the methods it knows for producing new copies of objects. Essentially, it's a dictionary of the type of object and the "function to produce a new object" -- this "function to produce a new object" is pretty much what you write when you write a __reduce__ or a __reduce_ex__ method for an object (and if one of those is missing or needs help, it defers to the __setstate__, __getstate__, etc methods.
So that's copy. Basically… (with some additional clauses…)
def copy(x):
"""Shallow copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
cls = type(x)
copier = _copy_dispatch.get(cls)
if copier:
return copier(x)
copier = getattr(cls, "__copy__", None)
if copier:
return copier(x)
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(2)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error("un(shallow)copyable object of type %s" % cls)
deepcopy does the same thing as the above, but in addition inspects each object and makes sure that there's a copy for each new object and not a pointer reference. deepcopy builds it's own _deepcopy_dispatch table (a dict) where it registers functions that ensure the new objects produced do not have pointer references to the originals (possibly generated with the __reduce__ functions registered in copy_reg.dispatch_table)
Hence writing a __reduce__ method (or similar) and registering it with copy_reg, should enable copy and deepcopy to do their thing as well.