Semi-newbie, rolling my own __deepcopy__
ladasky at my-deja.com
ladasky at my-deja.com
Wed Apr 6 07:34:25 EDT 2005
Michael Spencer wrote:
> ladasky at my-deja.com wrote:
[snip]
> > Anyway, my present problem is that I want to make copies of
instances
> > of my own custom classes. I'm having a little trouble
understanding
> > the process. Not that I think that it matters -- but in case it
does,
> > I'll tell you that I'm running Python 2.3.4 on a Win32 machine.
[snip]
> If you google for:
> python __deepcopy__ cookbook
> you will find a couple of examples of this method in use, among them:
> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/259179
>
> 1 class deque(object):
> 2
> 3 def __init__(self, iterable=()):
> 4 if not hasattr(self, 'data'):
> 5 self.left = self.right = 0
> 6 self.data = {}
> 7 self.extend(iterable)
>
> [...snip methods...]
>
> 8 def __deepcopy__(self, memo={}):
> 9 from copy import deepcopy
> 10 result = self.__class__()
> 11 memo[id(self)] = result
> 12 result.__init__(deepcopy(tuple(self), memo))
> 13 return result
>
> HTH
> Michael
Hi, Michael,
I was indeed finding code like this in my web searches, though not this
particular example. I'm glad that you cut out code that is irrelevant
to the deepcopy operation. Still, I want to understand what is going
on here, and I don't. I've numbered the lines in your example.
So, entering deepcopy, I encounter the first new concept (for me) on
line 10. We obtain the class/type of self. On line 11 we create a
dictionary item in memo, [id(self):type(self)]. So now I'm confused as
to the purpose of memo. Why should it contain the ID of the *original*
object?
Things get even stranger for me on line 12. Working from the inside of
the parentheses outward, an attempt is made to convert self to a tuple.
Shouldn't this generate a TypeError when given a complex, non-iterable
item like the deque class? I just tried running one of my programs,
which assigns the name "x" to one of my custom objects, and when I
execute tuple(x), a TypeError is what I get.
Anyway, I like what I think I see when you finally call __init__ for
the copied object, on lines 4-6. If __deepcopy__ calls __init__, then
the new deque object should already have a "data" attribute. So "data"
is only initialized if it doesn't already exist.
I do not understand whether the "iterable" variable, which appears on
lines 3 and 7, is relevant to the copying operation. Line 12 calls
__init__ with a single argument, not two, so iterable should be
declared as an empty tuple. Again I see what I think should generate a
TypeError on line 7, when an attempt is made to extend the non-sequence
object "self" with the iterable tuple.
Is there another section of the Python docs that will clarify all this
for me? I got hung up on all the "static", "public", etc. declarations
in Java early on. Python has taken me an awful lot farther, but
perhaps I'm hitting the conceptual wall again.
--
Rainforest laid low.
"Wake up and smell the ozone,"
Says man with chainsaw.
John J. Ladasky Jr., Ph.D.
More information about the Python-list
mailing list