Relationship between pickle and deepcopy

后端 未结 2 633
旧巷少年郎
旧巷少年郎 2020-12-18 18:13

What exactly is the relationship between pickle and copy.deepcopy? What mechanisms do they share, and how?

It is clear the two ar

2条回答
  •  鱼传尺愫
    2020-12-18 18:38

    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.

提交回复
热议问题