__slots__ and multiple inheritance

Carl Banks imbosol at vt.edu
Sat Dec 14 17:54:47 EST 2002


Dave Reed wrote:
> On Saturday 14 December 2002 15:53, Carl Banks wrote:
>> Dave Reed wrote:
>> > 
>> > __slots__ doesn't seem to work as I expect when I use 
> mixins/multiple
>> > inheritance:
>> > 
>> > I've got a BaseSQL class (see code at bottom of message) in which I
>> > define __slots__ (I started using it so pychecker didn't complain
>> > about me using the instance variables from the other base class). I
>> > left out "values" from __slots__, but it still lets me assign to
>> > self.values.
>> > 
>> > Also, If I put the same __slots__ in the StudentSQL class, I get the
>> > error:
>> > 
>> >    class Student(BaseSQL, StudentSQL):
>> > TypeError: multiple bases have instance lay-out conflict
>> > 
>> > Can anyone explain to me how this should work?
>> 
>> It doesn't work at all.  It seems kind of stupid at first, but you
>> can't inherit from two classes with slots (well, unless those classes'
>> slots are all inherited from a common base class).
> 
> I wasn't very clear - without the __slots__ in the the StudentSQL
> class, then it happily lets me access self.values in the BaseSQL class
> even though 'values' is not in the BaseSQL __slots__ list (and the
> other instance variables are). I expected to get an error when I tried
> to set self.values, but didn't.

Ok, I see what you're saying.  I'm sorry for not thoroughly reading
your message.

When you write self.values = whatever in BaseSQL.__init__, you are
asking Python to set the "values" attribute of the object "self".
However, "self" is an instance of Student, not BaseSQL.  An instance
of Student is not bound to BaseSQL's slots; it can freely define
attributes of its own; and because it doesn't have slots itself, it
uses a dict to store its attributes.  So, when you set the "values"
attribute of "self", it sees that "values" is not the name of any
slot, but also sees that "self" has a dict, so it stores the attribute
there.

Make sense?

This happens even when self.values is set with the class definition of
BaseSQL.




> Regarding the second point:
> 
> I read the following from Guido's "Unifying Types and Classes in
> Python 2.2" but I don't quite understand it.
> 
>  There's no check to prevent name conflicts between the slots defined
>  in a class and the slots defined in its base classes. If a class
>  defines a slot that's also defined in a base class, the instance
>  variable defined by the base class slot is inaccessible (except by
>  retrieving its descriptor directly from the base class; this could
>  be used to rename it). Doing this renders the meaning of your
>  program undefined; a check to prevent this may be added in the
>  future.
> 
> It appears to me that you could have __slots__ in both base classes
> as long as they intersection of the lists is empty (I'm pretty certain
> I tried that and it didn't work either).

That's not correct.  This paragraph says nothing about the case of two
base classes with slots.  What it says is that, if your derived class
defines a slot with the same name as a slot in your base class, then
the slot in the base class is inaccessible, shadowed by the derived
class.

Trust me, having two base classes with their own slots is simply
impossible with the way they do it now, because the bases store their
slots in the same place.


-- 
CARL BANKS



More information about the Python-list mailing list