newbie: copy base class fields

Alex Martelli aleax at mac.com
Thu May 3 10:51:21 EDT 2007


tmp123 <tmp123 at menta.net> wrote:
   ...
> It seems that the statement "self=a" is not the correct way to copy
> all the fields of the base class from the __init__ argument to the new
> object.

Indeed, it isn't.  Assigning to self just rebinds the name 'self' as a
local variable of method B.__init__ -- really useless.

> Of course, it is not an option to copy one by one all the fields of
> class A inside the __init__ of B.
> 
> Several variants of the program produces similar results.
> 
> Please, could someone explain which way is the correct way?

Somebody else suggested you call A.__init__ from inside B.__init__, and
that is correct if what you want to do is "freshly initialize the B
instance as an A".  However, from the fact that you pass to B.__init__
an argument 'a', it looks as if what you're trying to do is indeed copy
each of a's instance variables to self (it's hard to read your mind from
the code you've posted, but if I had to guess that would be by guess),
where a is an instance of A that's not necessarily "freshly
initialized".

In this case, you might for example start B.__init__ with:
    self.__dict__.update(a.__dict__)

This is not very elegant or solid, but at least it's short and fast:-).

A better way would require having _somewhere_ a list or tuple with the
names of all the instance variables you know you want to copy; if that
list of names was for example B._names_to_copy,
    for name in self._names_to_copy:
        value = getattr(a, name)
        setattr(self, name, value)
IS elegant and robust.  The advantages of explicitly controlling what
names you're copying (rather than blindly taking whatever happens to be
there) are similar to those of avoiding "from wherever import *": you
avoid accidental name pollution.  The advantages of using getattr and
setattr (rather than blindly working on the __dict__s) are those of
working correctly and transparently with properties and other similar
kinds of descriptors, rather than just "raw" instance variables.


Alex



More information about the Python-list mailing list