__slots__ and multiple inheritance

Dave Reed dreed at capital.edu
Sun Dec 15 08:53:19 EST 2002


On Saturday 14 December 2002 17:54, Carl Banks wrote:
> 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.



Thanks, I think I got it now. I was thinking that the __slots__ would
be inherited from the base class, but that's not the case.


> > 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.


Thanks,
Dave





More information about the Python-list mailing list