deepcopy problem
Stephen C Phillips
news at scphillips.co.uk
Mon Mar 10 09:55:54 EST 2003
Hi,
I am having a problem with copy.deepcopy() in Python 2.2.2.
The problem only arises when I use classes derived from the object
class. Apologies if this is a known bug - I hope it is just my
own incompetence.
Sorry about the long example listing:
import copy
class Node:
count = 1
def __init__(self):
self.paths = []
self.index = Node.count
Node.count += 1
pass
def __str__(self):
paths = ', '.join(map(lambda n: str(n.index), self.paths))
return "(%s) Node %s: paths [%s]" % (hex(id(self)), self.index, paths)
def __getstate__(self):
print 'getting node state'
print self
return self.__dict__
def __setstate__(self, state):
print 'setting node state', hex(id(self))
print state
self.__dict__.update(state)
def add_path(self, path):
self.paths.append(path)
class Path:
count = 1
def __init__(self, nodes):
self.nodes = nodes
self.index = Path.count
Path.count += 1
for node in nodes:
node.add_path(self)
def __str__(self):
nodes = ', '.join(map(lambda n: str(n.index), self.nodes))
return "(%s) Path %s: nodes [%s]" % (hex(id(self)), self.index, nodes)
def __getstate__(self):
print 'getting path state'
print self
return self.__dict__
def __setstate__(self, state):
print 'setting path state', hex(id(self))
print state
self.__dict__.update(state)
n = Node()
m = Node()
p = Path([n,m])
print n
print m
print p
print '-----'
x = copy.deepcopy(n)
print '-----'
print x
print x.paths[0]
for node in x.paths[0].nodes: print node
----------------------------------------
The output of this is as you would hope:
(0x8180c5c) Node 1: paths [1]
(0x8184484) Node 2: paths [1]
(0x819441c) Path 1: nodes [1, 2]
-----
getting node state
(0x8180c5c) Node 1: paths [1]
getting path state
(0x819441c) Path 1: nodes [1, 2]
getting node state
(0x8184484) Node 2: paths [1]
setting node state 0x8181ab4
{'paths': [<__main__.Path instance at 0x818463c>], 'index': 2}
setting path state 0x818463c
{'index': 1, 'nodes': [<__main__.Node instance at 0x81097b4>, <__main__.Node instance at 0x8181ab4>]}
setting node state 0x81097b4
{'paths': [<__main__.Path instance at 0x818463c>], 'index': 1}
-----
(0x81097b4) Node 1: paths [1]
(0x818463c) Path 1: nodes [1, 2]
(0x81097b4) Node 1: paths [1]
(0x8181ab4) Node 2: paths [1]
If you change the classes to be derived from object, e.g.
class Node(object):
etc
class Path(object):
etc
then the output is this:
(0x8101484) Node 1: paths [1]
(0x811f6bc) Node 2: paths [1]
(0x81844f4) Path 1: nodes [1, 2]
-----
getting node state
(0x8101484) Node 1: paths [1]
getting path state
(0x81844f4) Path 1: nodes [1, 2]
getting node state
(0x8101484) Node 1: paths [1]
setting node state 0x8181824
{}
getting node state
(0x811f6bc) Node 2: paths [1]
getting path state
(0x81844f4) Path 1: nodes [1, 2]
setting path state 0x81858ac
{'index': 1}
setting node state 0x818189c
{'paths': [<__main__.Path object at 0x81858ac>], 'index': 2}
setting path state 0x819354c
{'index': 1, 'nodes': [<__main__.Node object at 0x8181824>, <__main__.Node object at 0x818189c>]}
setting node state 0x8111eb4
{'paths': [<__main__.Path object at 0x819354c>], 'index': 1}
-----
(0x8111eb4) Node 1: paths [1]
Traceback (most recent call last):
File "/steve/project/debug/stick.py", line 72, in ?
print x.paths[0]
File "/steve/project/debug/stick.py", line 44, in __str__
nodes = ', '.join(map(lambda n: str(n.index), self.nodes))
File "/steve/project/debug/stick.py", line 44, in <lambda>
nodes = ', '.join(map(lambda n: str(n.index), self.nodes))
AttributeError: 'Node' object has no attribute 'index'
The error is still present when the __getstate__ and __setstate__ methods
are removed. Their only purpose is for illustration.
Can anyone help?
Stephen Phillips.
More information about the Python-list
mailing list