deepcopy problem
Stephen C Phillips
news at scphillips.co.uk
Tue Mar 11 05:03:29 EST 2003
Hi,
I have refined my problem and have a smaller example now. I have a
class called 'Node' which is a new-style class and has a name and a
'neighbour' which is another Node object. I make a node 'n' and a node
'm' and point n at m AND m at n, so n.neighbour.neighbour is n. I then do
a deepcopy of n into x. This of course makes a copy of m too. I then
print x (and it looks just like n) but the dictionary of
x.neighbour.neighbour is empty and x.neighbour.neighbour is not x.
If I make Node an old-style class (by just using "class Node:") then it
all works fine and x.neighbour.neighbour is x. I am using Python 2.2.2.
Can anyone explain what difference between old and new-style classes causes this
please?
Once again, the __getstate__() and __setstate__() methods are in there
just to help diagnose the problem and the code works the same without
them.
Thanks.
Stephen Phillips.
--------------------------------
import copy
class Node:
def __init__(self, name):
self.name = name
self.neighbour = None
def __str__(self):
return "Node %s: neighbour %s" % (self.name, self.neighbour.name)
def __getstate__(self):
print 'getting node state', hex(id(self))
print ' ', self.__dict__
return self.__dict__
def __setstate__(self, state):
print 'setting node state', hex(id(self))
print ' ', state
self.__dict__.update(state)
n = Node('n')
m = Node('m')
n.neighbour = m
m.neighbour = n
print n
print m
print n.neighbour.neighbour is n
print
x = copy.deepcopy(n)
print
print x
print x.neighbour.neighbour.__dict__
print x.neighbour.neighbour is x
-------------------------------
This will produce something like:
Node n: neighbour m
Node m: neighbour n
1
getting node state 0x810bb6c
{'neighbour': <__main__.Node object at 0x8166b24>, 'name': 'n'}
getting node state 0x8166b24
{'neighbour': <__main__.Node object at 0x810bb6c>, 'name': 'm'}
getting node state 0x810bb6c
{'neighbour': <__main__.Node object at 0x8166b24>, 'name': 'n'}
setting node state 0x815f864
{}
setting node state 0x81662bc
{'neighbour': <__main__.Node object at 0x815f864>, 'name': 'm'}
setting node state 0x8166f8c
{'neighbour': <__main__.Node object at 0x81662bc>, 'name': 'n'}
Node n: neighbour m
{}
0
More information about the Python-list
mailing list