[Python-Dev] Meta-reflections

David Ascher DavidA@ActiveState.com
Wed, 20 Feb 2002 11:25:42 -0800


Kevin Jacobs wrote:

> Yes, though one implication of the new slots mechanism in Python 2.2 is that
> we now have have non-flat per-instance namespaces for slots.  i.e., we would
> have per-instance slots that would hide other per-instance slots of the same
> name from ancestor classes:
> 
>   class Base(object):
>      __slots__ = ['foo']
>      def __init__(self):
>        self.foo = 1          # which slot this sets depends on type(self)
>                              # if type(self) == Base, then the slot is
>                              # described by Base.foo.
>                              # else if type(self) == Derived, then the
>                              # slot is described by Derived.foo
> 
>    class Derived(Base):
>      __slots__ = ['foo']
>      def __init__(self):
>        Base.__init__(self)
>        self.foo = 2          # this is NOT the same foo as in Base
> 
>   o = Derived()
>   print o.foo
>   > 2
>   o.__class__.__base__.foo = 3
>   print o.foo
>   > 2
>   print o.__class__.__base__.foo
>   > 3
> 
> So slots, as currently implemented, do not act like attributes, and this
> whole discussion revolves around whether they should or should not.

This example is not a great example of that, since the code above does
exactly the same thing if you delete the lines defining __slots__. 
You're modifying class attributes in that case, but I think it's
important to keep the examples which illustrate the problem "pure" and
"realistic".

My take on this thread is that I think it's simply not going to happen
that slots are going to act 100% like attributes except for
performance/memory considerations.  It would be nice, but if that had
been possible, then they'd simply be an internal optimization and would
have no syntactic impact.

There are much more shallow ways in which slots aren't like attributes:

>>> class A(object):
...   __slots__ = ('a',)
...
>>> a = A()
>>> a.a = 123             # set a slot on a
>>> A.a = 555             # set a slot on A
>>> a.a                   # Way 1: A's slot overrides a's
555
>>> b = A()
>>> b.a                   
555
>>> del A.a
>>> a.a                   # Way 2: deleting the class slot
                          # did not uncover the instance slot
AttributeError: 'A' object has no attribute 'a'

--david