deepcopy problem with new-style classes in Python 2.3a2

Alex Martelli aleax at aleax.it
Wed Mar 12 13:21:51 EST 2003


Stephen C Phillips wrote:

> Hi,
> I am having a problem using deepcopy on a complex data structure.  I
> think it can be distilled down to a basic difficulty shown below (thanks
> to Jp Calderone).
> With Python 2.3a2 (or Python 2.2.2) I get this:
> 
>>>> class Foo(object):
> ...     pass
> ...
>>>> f = Foo()
>>>> f.foo = f
>>>> g = copy.deepcopy(f)
>>>> g is not f
> True
>>>> f is f.foo
> True
>>>> g is g.foo
> False
> 
> Obviously I would like "g.foo is foo" to be True.
> g.foo is not f either, it is some other empty object.
> With old-style classes I get the desired behaviour.  Can anyone explain
> what the problem is?

Module copy is currently not able to install a "proper" deep-copier function
that works automatically and correctly for instances of new-style classes,
in good part because it has no way to identify "instances of new-style
classes" as such (as opposed to, e.g., instances of subclasses of list, or
dict, etc -- they're all much the same thing, but need very different
approaches to deep-copying).

I suggest you submit this as a bug, and if you need a workaround you can
ensure your new-style classes contain a __deepcopy__ that satisfies your
needs, such as:

    def __deepcopy__(self, memo):
        x = Foo.__new__(Foo)
        memo[id(self)] = x
        for n, v in self.__dict__.iteritems():
            setattr(x, n, copy.deepcopy(v, memo))
        return x

for new-style classes whose instances hold all of their state in __dict__,
and so on.


Alex





More information about the Python-list mailing list