phil wrote: > >> The deepcopy protocol does allow you to specify how complicated >> objects should be copied. Try defining __deepcopy__() in your objects >> to just copy the reference to the Canvas object instead of the object >> itself. > > I can't figure out from the docs what __deepcopy__ is or how it > > works. > I have about 25 classes of drawn objects. for instance > class linefromslope creates an instance of class line. > One of my "ugly solutions" involves a class prop: within each class, > put properties like slope and midpoint within the self.prop instance > and making a copy of that. > Would __deepcopy__ facilitate this? > Or am I assuming too much: is __deepcopy__ just a method > I invent to do what I want? >
The docs say: > In order for a class to define its own copy implementation, it can > define special methods __copy__() and __deepcopy__(). The former is > called to implement the shallow copy operation; no additional > arguments are passed. The latter is called to implement the deep copy > operation; it is passed one argument, the memo dictionary. If the > __deepcopy__() implementation needs to make a deep copy of a > component, it should call the deepcopy() function with the component > as first argument and the memo dictionary as second argument. __deepcopy__ is a method which overrides the default way to make a deepcopy of an object. So, if you have a class with attributes a, b, and c, and you want to ensure that deepcopy copies a and b, but doesn't copy c, I guess you could do something like: >>> class MyClass: _dontcopy = ('c',) # Tuple of attributes which must not be copied def __deepcopy__(self, memo): clone = copy.copy(self) # Make a shallow copy for name, value in vars(self).iteritems(): if name not in self._dontcopy: setattr(clone, name, copy.deepcopy(value, memo)) return clone >>> class Copyable(object): def __new__(cls, *args): print "created new copyable" return object.__new__(cls, *args) >>> m = MyClass() >>> m.a = Copyable() created new copyable >>> m.b = Copyable() created new copyable >>> m.c = Copyable() created new copyable >>> clone = copy.deepcopy(m) created new copyable created new copyable >>> m.a is clone.a False >>> m.c is clone.c True >>> As you can see, the deepcopy only creates deep copies of 2 of the 3 attributes, 'c' is simply copied across as a shallow copy. and if you subclass MyClass you can modify the _dontcopy value to add additional attributes which must not be copied. -- http://mail.python.org/mailman/listinfo/python-list