Copying objects and multiple inheritance

Brian Allen Vanderburg II BrianVanderburg2 at
Wed Jun 3 09:20:35 EDT 2009

Gabriel Genellina wrote:
> En Tue, 02 Jun 2009 19:02:47 -0300, Brian Allen Vanderburg II 
> <BrianVanderburg2 at> 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]
> [2]
> [3]
> [4]
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):

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

    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

        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

More information about the Python-list mailing list