More On - deepcopy, Tkinter

phil phillip.watts at anvilcom.com
Wed Jul 6 10:33:55 EDT 2005


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.
> 






More information about the Python-list mailing list