[Tutor] Challenge supporting custom deepcopy with inheritance

Michael H. Goldwasser goldwamh at slu.edu
Mon Jun 1 05:28:12 CEST 2009


Hi Kent,

Thanks for your thoughts. 

For the original example code, you are correct that we could make it
work by having B provide the one-arg constructor to match A's
constructor signature.  But I don't see this as a general solution.

Having B.__deepcopy__() make a call to A.__deepcopy__() assumes that A
supports __deepcopy__ either direclty or indirectly.  This is not
guaranteed as __deepcopy__ is not supported all the way back to the
object base class.  It could be that the author of A has guaranteed
that the syntax deepcopy(instanceA) is properly supported, but that
could be done by other means without an explicit __deepcopy__ (such as
relying on a true deep copy, or using getstate/setstate to affect both
pickling and deepcopy).

As another basic puzzle, consider a class definition for B where B has
a registry list that it doesn't want cloned for the new instance (but
it does want pickled when serialized).  This would seem to require
that B implement its own __deepcopy__.   We want to somehow rely on
the class definition for A to enact the cloning fo the state defined
by A.   But without knowing about how A supports the deepcopy
semantics, I don't see how to accomplish this goal.

class B(A):
    def __init__(self):
        self.__registry = []

    def register(self, obj):
        self.__registry.append(obj)

    def __deepcopy__(self, memo={}):
        dup =  ????     # would like something like A's version of deepcopy(self,memo)
                        # as our starting point but we need an instance of class B
                        # and B.__deepcopy__ masks our ability to rely on the
                        # inherited semantics of deepcopy(self)
        dup.__registry = []
        memo[id(self)] = dup
        return dup


On Sunday May 31, 2009, Kent Johnson wrote: 

>    On Sun, May 31, 2009 at 5:35 PM, Michael H. Goldwasser <goldwamh at slu.edu> wrote:
>    >
>    > Yesterday, I posted a question to python-list involving custom
>    > deepcopies in an inheritance hierarchy.  I haven't received any
>    > responses, so I thought I'd cross-post to see if anyone on tutor
>    > has any thoughts.
>    >
>    > To avoid splitting the thread, I'll simply reference the original post at
>    > http://mail.python.org/pipermail/python-list/2009-May/714866.html
>    > and ask for responses to be sent there.
>    
>    Sorry, splitting the thread for you...
>    
>    ISTM that in general B.__deepcopy__() should call A.__deepcopy__() to
>    do the "A" part of the work. In your example, this won't work because
>    A.__deepcopy__() assumes that subclasses have a one-argument
>    constructor. So, I would say that B is not fulfilling the contract
>    assumed by A.
>    
>    What if you give B a one-arg constructor by making the bTag argument
>    optional? Then I think B.__deepcopy__() can call A.__deepcopy__(),
>    then do the "B" part of the copy on the result.
>    
>    Kent


       +-----------------------------------------------
       | Michael Goldwasser
       | Associate Professor
       | Dept. Mathematics and Computer Science
       | Saint Louis University
       | 220 North Grand Blvd.
       | St. Louis, MO 63103-2007
       |
       | Office: Ritter Hall 6
       | Email:  goldwamh at slu.edu
       | URL:    http://cs.slu.edu/~goldwasser
       | Phone:  (314) 977-7039
       | Fax:    (314) 977-1452




More information about the Python-list mailing list