Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #33987 > unrolled thread

deepcopy questions

Started bylars van gemerden <lars@rational-it.com>
First post2012-11-27 15:59 -0800
Last post2012-11-29 08:01 +0100
Articles 5 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  deepcopy questions lars van gemerden <lars@rational-it.com> - 2012-11-27 15:59 -0800
    Re: deepcopy questions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-28 00:46 +0000
    Re: deepcopy questions MRAB <python@mrabarnett.plus.com> - 2012-11-28 00:59 +0000
    Re: deepcopy questions lars van gemerden <lars@rational-it.com> - 2012-11-28 01:05 -0800
      Re: deepcopy questions Dieter Maurer <dieter@handshake.de> - 2012-11-29 08:01 +0100

#33987 — deepcopy questions

Fromlars van gemerden <lars@rational-it.com>
Date2012-11-27 15:59 -0800
Subjectdeepcopy questions
Message-ID<bbed43a4-457d-45c3-bc84-519d51516431@googlegroups.com>
Hi,

I get a very strange result when using deepcopy. The following code:

    def __deepcopy__(self, memo):
        independent = self.independent()
        if independent is self:
            out = type(self)()
            out.__dict__ = copy.deepcopy(self.__dict__, memo)
            print self.__dict__
            print out.__dict__ #strange result
            return out
        else:
            return copy.deepcopy(independent, memo).find(self.id).take()

prints different results for self.__dict__ and out.__dict__:

{'_active_': False, 'init': {}, '_id_': 0, '_items_': [<flow.library.collector object at 0x03893910>], '_name_': 'main'} 
{'_active_': False, 'init': {}, '_id_': 0}

Two items are missing in the copy. Maybe i am missing something obvious, but i cannot figure out how this could happen.

Can anyone tell me how this is possible?

Cheers, Lars 

[toc] | [next] | [standalone]


#33989

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-11-28 00:46 +0000
Message-ID<50b55eea$0$21750$c3e8da3$76491128@news.astraweb.com>
In reply to#33987
On Tue, 27 Nov 2012 15:59:38 -0800, lars van gemerden wrote:

> Hi,
> 
> I get a very strange result when using deepcopy. The following code:
> 
>     def __deepcopy__(self, memo):
>         independent = self.independent()
>         if independent is self:
>             out = type(self)()
>             out.__dict__ = copy.deepcopy(self.__dict__, memo) 
>             print self.__dict__
>             print out.__dict__ #strange result
>             return out
>         else:
>             return copy.deepcopy(independent, memo).find(self.id).take()
> 
> prints different results for self.__dict__ and out.__dict__:

What makes you think that this is a strange result? What result are you 
expecting?

> {'_active_': False, 'init': {}, '_id_': 0, '_items_':
> [<flow.library.collector object at 0x03893910>], '_name_': 'main'}
> {'_active_': False, 'init': {}, '_id_': 0}
> 
> Two items are missing in the copy. Maybe i am missing something obvious,
> but i cannot figure out how this could happen.
> 
> Can anyone tell me how this is possible?

The most obvious guess is that the memo dict already contains _items_ and 
_names_, and so they get skipped.

Please ensure your sample code can be run. You should create the simplest 
example of stand-alone code that other people can run. See more 
information here:

http://sscce.org/


By the way, is it just me or is the documentation for deepcopy seriously 
lacking? http://docs.python.org/3/library/copy.html

There's no mention of the additional arguments memo and _nil, and while 
the docs say to pass the memo dictionary to __deepcopy__ it doesn't 
document any restrictions on this memo, how to initialise it, or under 
what circumstances you would pass anything but an empty dict.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#33990

FromMRAB <python@mrabarnett.plus.com>
Date2012-11-28 00:59 +0000
Message-ID<mailman.325.1354064354.29569.python-list@python.org>
In reply to#33987
On 2012-11-27 23:59, lars van gemerden wrote:
> Hi,
>
> I get a very strange result when using deepcopy. The following code:
>
>      def __deepcopy__(self, memo):
>          independent = self.independent()
>          if independent is self:
>              out = type(self)()
>              out.__dict__ = copy.deepcopy(self.__dict__, memo)
>              print self.__dict__
>              print out.__dict__ #strange result
>              return out
>          else:
>              return copy.deepcopy(independent, memo).find(self.id).take()
>
> prints different results for self.__dict__ and out.__dict__:
>
> {'_active_': False, 'init': {}, '_id_': 0, '_items_': [<flow.library.collector object at 0x03893910>], '_name_': 'main'}
> {'_active_': False, 'init': {}, '_id_': 0}
>
> Two items are missing in the copy. Maybe i am missing something obvious, but i cannot figure out how this could happen.
>
> Can anyone tell me how this is possible?
>
I haven't been able to reproduce the problem.

Could you provide a self-contained and _runnable_ piece of code that
shows the problem?

[toc] | [prev] | [next] | [standalone]


#34004

Fromlars van gemerden <lars@rational-it.com>
Date2012-11-28 01:05 -0800
Message-ID<39edd363-2937-48a8-b84d-54d3993e42cf@googlegroups.com>
In reply to#33987
On Wednesday, November 28, 2012 12:59:38 AM UTC+1, lars van gemerden wrote:
> Hi,
> 
> 
> 
> I get a very strange result when using deepcopy. The following code:
> 
> 
> 
>     def __deepcopy__(self, memo):
> 
>         independent = self.independent()
> 
>         if independent is self:
> 
>             out = type(self)()
> 
>             out.__dict__ = copy.deepcopy(self.__dict__, memo)
> 
>             print self.__dict__
> 
>             print out.__dict__ #strange result
> 
>             return out
> 
>         else:
> 
>             return copy.deepcopy(independent, memo).find(self.id).take()
> 
> 
> 
> prints different results for self.__dict__ and out.__dict__:
> 
> 
> 
> {'_active_': False, 'init': {}, '_id_': 0, '_items_': [<flow.library.collector object at 0x03893910>], '_name_': 'main'} 
> 
> {'_active_': False, 'init': {}, '_id_': 0}
> 
> 
> 
> Two items are missing in the copy. Maybe i am missing something obvious, but i cannot figure out how this could happen.
> 
> 
> 
> Can anyone tell me how this is possible?
> 
> 
> 
> Cheers, Lars

I have just tried to make a simple runnable testcase but no luck. in my code it's part of a rather complex data structure. 

As I understood the documentation, the memo parameter is to hold a dictionary of data that have already been copied (e.g. to deal with circular references), and is normally only explicitly used when implementing __deepcopy__, just passing memo to calls to deepcopy within the body of __deepcopy__.

If memo contains items, this should, to my understanding, not remove them from the output of deepcopy, they will just not be copied again, but instead be taken from memo and put in the output (otherwise 2 references to the same object would after deepcopying result in 2 distinct copies of that object).

Anyway, since i cannot reproduce the error in a simple testcase and i have no adea what is going on, I'll implement what i need differently.

Any ideas are still more then welcome,

Thanks for the feedback,

Lars

[toc] | [prev] | [next] | [standalone]


#34051

FromDieter Maurer <dieter@handshake.de>
Date2012-11-29 08:01 +0100
Message-ID<mailman.356.1354172588.29569.python-list@python.org>
In reply to#34004
lars van gemerden <lars@rational-it.com> writes:
> ... "deepcopy" dropping some items ...
> Any ideas are still more then welcome,

"deepcopy" is implemented in Python (rather than "C").
Thus, if necessary, you can debug what it is doing
and thereby determine where the items have been dropped.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web