Gabriel Genellina wrote:
En Tue, 02 Jun 2009 19:02:47 -0300, Brian Allen Vanderburg II <brianvanderbu...@aim.com> escribió:

What is the best way to copy an object that has multiple inheritance with the copy module. Particularly, some of the instances in the hierarchy

("...some of the classes in...", I presume?)

use the __copy__ method to create a copy (because even for shallow copies they need some information updated a little differently), so how can I make sure all the information is copied as it is supposed to be even for the base classes that have special requirements.

If you don't control all the clases involved, there is little hope for a method like __copy__ to work at all... All classes must be written with cooperation in mind, using super() the "right" way. See "Python's Super Considered Harmful" [1] and "Things to Know About Python Super" [2][3][4]

That said, and since multiple inheritance is the heart of the problem, maybe you can redesign your solution *without* using MI? Perhaps using delegation instead?

[1] http://fuhm.net/super-harmful/
[2] http://www.artima.com/weblogs/viewpost.jsp?thread=236275
[3] http://www.artima.com/weblogs/viewpost.jsp?thread=236278
[4] http://www.artima.com/weblogs/viewpost.jsp?thread=237121

I do control the classes involved. A problem I was having, but I think I now got solved, is if using super, the copy would not have the same class type. Also, a problem was if using super, but some class in the hierarchy didn't implement __copy__, then it's data would not be copied at all. This was also fixed by copying the entire __dict__ in the base __copy__. This is an idea of what I got, it seems to be working fine:

import copy

class _empty(object):
   pass

class Base(object):
   def __init__(self):
       pass

   def __copy__(self):
       // don't use copy = Base()
       // Also don't call self.__class__() because it may have a custom
       // __init__ which take additional parameters
       copy = _empty()
       copy.__class__ = self.__class__
       // In case a class does not have __copy__ (such as B below), make
       // sure all items are copied
       copy.__dict__.update(self.__dict__)

       return copy

class A(Base):
   def __init__(self):
       super(A, self).__init__()
       self.x = 13

   def __copy__(self):
       copy = super(A, self).__copy__()
       copy.x = self.x * 2
       return copy

class B(Base):
   def __init__(self):
       super(B, self).__init__()
       self.y = 14

   #def __copy__(self):
   #    copy = super(B, self).__copy__()
   #    copy.y = self.y / 2
   #    return copy

class C(A, B):
   def __init__(self):
       super(C, self).__init__()
       self.z = 64

   def __copy__(self):
       copy = super(C, self).__copy__()
       copy.z = self.z * self.z
       return copy

o1 = C()
o2 = copy.copy(o1)

print type(o1), o1.x, o1.y, o1.z
print type(o2), o2.x, o2.y, o2.z


--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to