__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