[Tutor] question about __copy__ and __deepcopy__
Albert-Jan Roskam
sjeik_appie at hotmail.com
Thu Apr 14 15:38:31 EDT 2016
Hi,
Lately I have been using the "mutable namedtuple" shown below a lot. I found it somewhere on StackOverflow or ActiveState or something.
In its original form, it only had an __init__ method. I noticed that copying Record objects sometimes failed. So I implemented __copy__ and __deepcopy__,
Is this the correct way to do this? In my original use case, even shallow copies failed, but I can't reproduce that anymore (or maybe I am imagining things!).
Is __copy__ really needed here? Does __deepcopy__ make any sense at all? My tests pass, but still I am not sure!
Thanks!
Albert-Jan
from copy import copy, deepcopy
class Record(dict):
def __init__(self, *args, **kwargs):
super(Record, self).__init__(*args, **kwargs)
self.__dict__ = self
def __str__(self):
items = ["%r: %r" % (k, v) for k, v in sorted(self.__dict__.items())]
return "{" + ", ".join(items) + "}"
def __copy__(self):
return Record(**self.__dict__.copy())
def __deepcopy__(self, memo):
address = id(self)
try:
return memo[address]
except KeyError:
memo[address] = {k: copy(v) for k, v in self.items()}
return deepcopy(self, memo)
if __name__ == "__main__":
# only shallow needed
record = Record(x=1, y=2, z=3)
cp = copy(record)
assert record == cp and not record is cp
record = Record(x=1, y=2, z=3)
dc = deepcopy(record)
assert record == dc and not record is dc
# mutable value: deepcopy needed
L = range(10)
record = Record(x=1, y=2, z=L)
cp = copy(record)
print record, cp
assert record == cp and not record is cp
dc = deepcopy(record)
assert record == dc and not record is dc
L.insert(0, 42)
expect = {'y': 2, 'x': 1, 'z': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
assert dc == expect and not record is dc
print record, dc
More information about the Tutor
mailing list