[Tutor] Challenge supporting custom deepcopy with inheritance
Michael H. Goldwasser
goldwamh at slu.edu
Sun May 31 23:28:12 EDT 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