[EMAIL PROTECTED] wrote:
Michael Spencer wrote:

[EMAIL PROTECTED] 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

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?

Note that you obtain *and then call* the class/type of self:

py> i, s = 100, 'string'
py> i.__class__, s.__class__
(<type 'int'>, <type 'str'>)
py> i.__class__(), s.__class__()
(0, '')

So you've created a new object calling the constructor with no arguments. So 'result' is a new instance of the class.

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.

tuple(x) works on any object that defines __iter__:

py> class C(object):
...     def __iter__(self):
...         yield 1
...         yield 2
...         yield 5
...
py> tuple(C())
(1, 2, 5)

So line 12 is making a tuple of the values in the object, and then calling result's __init__ again, this time with (a deepcopied) tuple as an argument. This adds the content to the previously uninitialized object.

HTH,

STeVe
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to