trouble with copy/deepcopy

  • Thread starter Alexander Zatvornitskiy
  • Start date
A

Alexander Zatvornitskiy

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, (e-mail address removed)
 
L

ladasky

Alexander said:
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, (e-mail address removed)


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/comp.lang.python/browse_frm/thread/41269228e1827a87

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!
 
M

Marc 'BlackJack' Rintsch

Alexander Zatvornitskiy said:
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
 
A

Alexander Zatvornitskiy

ðÒÉ×ÅÔ 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, (e-mail address removed)
 
P

Peter Otten

Alexander said:
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:
.... q = 0 # class variable
....0

Peter
 
M

Mike Meyer

ðÒÉ×ÅÔ 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
 
A

Alexander Zatvornitskiy

ðÒÉ×ÅÔ 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, (e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top