More On - deepcopy, Tkinter

Duncan Booth duncan.booth at invalid.invalid
Tue Jul 5 11:35:40 EDT 2005


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