470,561 Members | 1,928 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,561 developers. It's quick & easy.

trouble with copy/deepcopy

Hello!

I have trouble with copy/deepcopy. It seems, I just don't understand something.
Please explain where things goes wrong and how to do it the right way.

I have one class:

class Distribution:
__gr_on_transp=dict()
__ostatok_m=dict()
and so on

And, I want to make full copy of it:
d1=Distribution()
d2=copy.deepcopy(d1)

But, members-dictionaries are don't copied. For example if I will write:
d1.clear()
which clears all two dictionaries, I will find that d2's dictionaries are also
empty!!!

Now I'am using the quick-hack:

class Distribution:
__gr_on_transp=dict()
__ostatok_m=dict()
...
def my_copy(self):
d2=copy.deepcopy(self)
d2.__gr_on_transp=self.__gr_on_transp.copy()
d2.__ostatok_m=self.__ostatok_m.copy()
return d2

It's work well, but I don't understand why previous is wrong and how to do it
in right way.

Alexander, za**@bk.ru
Jul 19 '05 #1
6 2078

Alexander Zatvornitskiy wrote:
Hello!

I have trouble with copy/deepcopy. It seems, I just don't understand something. Please explain where things goes wrong and how to do it the right way.
I have one class:

class Distribution:
__gr_on_transp=dict()
__ostatok_m=dict()
and so on

And, I want to make full copy of it:
d1=Distribution()
d2=copy.deepcopy(d1)

But, members-dictionaries are don't copied. For example if I will write: d1.clear()
which clears all two dictionaries, I will find that d2's dictionaries are also empty!!!

Now I'am using the quick-hack:

class Distribution:
__gr_on_transp=dict()
__ostatok_m=dict()
...
def my_copy(self):
d2=copy.deepcopy(self)
d2.__gr_on_transp=self.__gr_on_transp.copy()
d2.__ostatok_m=self.__ostatok_m.copy()
return d2

It's work well, but I don't understand why previous is wrong and how to do it in right way.

Alexander, za**@bk.ru

Hello, Alexander,

I just asked about deepcopy here in comp.lang.python a few weeks ago.
Here is a link to that discussion:

http://groups-beta.google.com/group/...269228e1827a87

You have the right idea when you create a special method inside your
class to handle the deepcopy operation. But if you call that method
__deepcopy__, then copy.deepcopy() can find it and call it.

In my code, it was also important that I declare my class as a
new-style class, so that I could use the __new__ method. __new__
constructs a new instance of the class without initializing it.

To make your class into a new-style class, you would write "class
Distribution(object):" instead of just "class Distribution:".

There are more details in the discussion that I referenced above. Hope
that helps!

--
Rainforest laid low.
"Wake up and smell the ozone,"
Says man with chainsaw.
John J. Ladasky Jr., Ph.D.

Jul 19 '05 #2
In <MS*****************************@fidonet.org>, Alexander Zatvornitskiy
wrote:
class Distribution:
__gr_on_transp=dict()
__ostatok_m=dict()
and so on
Those two dicts are *class variables* not *instance variables*!
And, I want to make full copy of it:
d1=Distribution()
d2=copy.deepcopy(d1)

But, members-dictionaries are don't copied. For example if I will write:
d1.clear()
which clears all two dictionaries, I will find that d2's dictionaries are also
empty!!!


That clears only one dictionary at class level. Which is visible on both
instances.

class Distribution:
def __init__(self):
self.__gr_on_transp = dict()
self.__ostatok_m = dict()
...

This creates *instance variables* which should be deepcopied without
problems.

Ciao,
Marc 'BlackJack' Rintsch
Jul 19 '05 #3
Привет Marc!

16 мая 2005 в 22:18, Marc 'BlackJack' Rintsch в своем письме к All писал:

MR> That clears only one dictionary at class level. Which is visible on
MR> both instances.

MR> class Distribution:
MR> def __init__(self):
MR> self.__gr_on_transp = dict()
MR> self.__ostatok_m = dict()
MR> ...

MR> This creates *instance variables* which should be deepcopied
MR> without problems.
Hmm. I don't find definition of "class variable" in manual. I try to test it on
such a simple test and find that such variable is NOT shared between copies:

class C:
q=int()

c1=C()
c2=C()
c1.q=5
c2.q=10
print c1.q
#5
print c2.q
#10

After deepcopy of c1 or c2, all classes have own copy of q. After replacing
integer q on dictionary, results are the same. There is an error?

Alexander, za**@bk.ru
Jul 19 '05 #4
Alexander Zatvornitskiy wrote:
Hmm. I don't find definition of "class variable" in manual. I try to test
it on such a simple test and find that such variable is NOT shared between
copies:

class C:
q=int()

c1=C()
c2=C()
c1.q=5
c2.q=10
print c1.q
#5
print c2.q
#10


Your test is flawed:
class C: .... q = 0 # class variable
.... c = C()
C.__dict__ {'q': 0, '__module__': '__main__', '__doc__': None} c.__dict__ {} c.q 0 c.q = 42 # this is stored in the instance, not the class
c.__dict__ {'q': 42} C.__dict__ {'q': 0, '__module__': '__main__', '__doc__': None} c.q 42 del c.q
c.q # because C.q is looked up as a fallback, 0 magically reappears

0

Peter

Jul 19 '05 #5
Al*********************@p131.f3.n5025.z2.fidonet.o rg (Alexander Zatvornitskiy) writes:
Привет Marc!

16 мая 2005 в 22:18, Marc 'BlackJack' Rintsch в своем письме к All писал:

MR> That clears only one dictionary at class level. Which is visible on
MR> both instances.

MR> class Distribution:
MR> def __init__(self):
MR> self.__gr_on_transp = dict()
MR> self.__ostatok_m = dict()
MR> ...

MR> This creates *instance variables* which should be deepcopied
MR> without problems.
Hmm. I don't find definition of "class variable" in manual. I try to test it on
such a simple test and find that such variable is NOT shared between copies:


Actually, it is shared - but only for reference. If you assign to it,
you'll create an instance variable of the same name. As Peter
explained, if you remove the instance variable, the class variable
becomes visible again. Try this:

py> class C:
.... q = []
....
py> c1 = C()
py> c2 = C()
py> c3 = C()
py> c1.q.append(1)
py> c2.q.append(2)
py> c3.q.append(3)
py> c1.q, c2.q, c3.q
([1, 2, 3], [1, 2, 3], [1, 2, 3])
py>

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 19 '05 #6
Привет Mike!

17 мая 2005 в 16:38, Mike Meyer в своем письме к Alexander Zatvornitskiy писал:
MM> Actually, it is shared - but only for reference. If you assign to it,
MM> you'll create an instance variable of the same name. As Peter
MM> explained, if you remove the instance variable, the class variable
MM> becomes visible again. Try this:
py>> class C:
MM> ... q = []
MM> ...
py>> c1 = C()
py>> c2 = C()
py>> c3 = C()
py>> c1.q.append(1)
py>> c2.q.append(2)
py>> c3.q.append(3)
py>> c1.q, c2.q, c3.q
MM> ([1, 2, 3], [1, 2, 3], [1, 2, 3])
py>>

It's true. Surpise!
Hence, every "non-static in c++-meaning" variable must be initialized in
constructor. It seems strange for me.

Thank you for explanation!

Alexander, za**@bk.ru
Jul 19 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Andreas Kuntzagk | last post: by
2 posts views Thread by Nick Jacobson | last post: by
reply views Thread by Joshua Ginsberg | last post: by
5 posts views Thread by mitsura | last post: by
3 posts views Thread by yoma | last post: by
1 post views Thread by livre | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.