Thanks, I used some of your methods and believe it is now working. I also did a lot of experiments, which I've needed to do, investigating when references vs values are passed and returned. Not as obvious as I thought.
Duncan Booth wrote: > 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