[Python-Dev] Meta-reflections

Kevin Jacobs jacobs@penguin.theopalgroup.com
Mon, 18 Feb 2002 20:51:48 -0500 (EST)

On 18 Feb 2002, Martin v. Loewis wrote:
> Kevin Jacobs <jacobs@penguin.theopalgroup.com> writes:
> >   1) Should class instances explicitly/directly know all of their attributes?
> Since types are classes, this is the same question as "should type
> instances know all their attributes?" I don't think they should, in
> general: For example, there is no way to find out whether a string
> object has an interned pointer, and I don't think there should be.

I explicitly made note that my discussion of slots was in the context of
native new-style Python class and not C-types, even ones that can be used as
bases class for other new-style classes.  We will always need to hide C
implementation details behind Python objects, but we are not talking about
reflection on such hidden state.  My belief is that slots should be treated
as much as possible like normal attributes and not as "hidden object state".

> class Spam(object):
>   __slots__ = ('a','b')
> s = Spam()
> s.a = {}
> del Spam.a
> you loose access to s.a, even though it is still available (I guess it
> is actually a bug that cyclic garbage collection won't find cycles
> involving slots).

Not exactly -- the semantics are the same as regular attributes in this
case.  Continuing your example, you can then do

  s.a = 5

so access to the slot is not lost, only to the value.

> >   2) Should attribute access follow the same resolution order rules as
> >      methods?
> Yes, I think so.

Ouch!  This implies a great deal more than you may be thinking of.  For
example, do you really want to be able to do this:

    class Foo(object):
      __slots__ = ('a',)

    class Bar(Foo):
      __slots__ = ('a',)

    bar = Bar()
    bar.a = 1
    super(Bar, bar).a = 2
    print bar.a
    > 1

This violates the traditional Python idiom of having a flat namespace for
attributes, even in the presence of inheritance.  This has very profound
implications to Python semantics and performance.

> >   4) Should __slots__ be flat?
> Yes. They should also be a property of the type, not a member of the
> dict of the type, and they should be a tuple of member object, not a
> list of strings. It might be reasonable to call this property
> __members__.
> >        > ('c','d')           # current behavior
> >        or
> >        > ('a','b','c','d')   # alternate behavior
> Neither, nor; assuming you meant Bar to inherit from Foo, it should be
> (<member 'a' of 'Foo' objects>, <member 'b' of 'Foo' objects>,
>  <member 'c' of 'Bar' objects>, <member 'd' of 'Bar' objects>)

An interesting idea that I had not considered.  Currently the slot
descriptor objects to not directly expose the name or type of the object
except in the repr.  This could easily be fixed.

However this brings up another issue.  The essence of a slot (or, more
correctly, a slot descriptor) is to store an offset into a PyObject* that
represents a value within an object.  The name to which the slot is bound is
not the intrinsic and defining characteristic.  So it would be somewhat
illogical to mandate static name bindings to slots.  This supports the
notion rebinding slot names during object inheritance (this is already
partially implemented), or storing the descriptor objects in a __slots__
tuple and providing an interface to query and reset the name binding for
each of them.

Comments?  Thoughts?


Kevin Jacobs
The OPAL Group - Enterprise Systems Architect
Voice: (216) 986-0710 x 19         E-mail: jacobs@theopalgroup.com
Fax:   (216) 986-0714              WWW:    http://www.theopalgroup.com