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 _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor