super, decorators and gettattribute

thebjorn BjornSteinarFjeldPettersen at gmail.com
Mon Jan 14 17:05:21 EST 2008


On Jan 14, 1:41 pm, Richard Szopa <ryszard.sz... at gmail.com> wrote:
> On Jan 13, 3:31 pm, thebjorn <BjornSteinarFjeldPetter... at gmail.com>
> wrote:
>
> > They do, except for when it comes to what super(..) returns. It isn't
> > really an object in the sense that they're presented in the tutorial,
> > but rather a sort of proxy to the methods in the ancestor classes of
> > the concrete object (self), relative to the current method's class. I
> > can't imagine that sentence would ease any confusion however, suffice
> > it to say that you have to call getattr(super(..), 'name') instead of
> > super(..).__getattr__('name') and you have to call super(..).__len__()
> > instead of len(super(..)) -- I can't imagine that lessens any
> > confusion either :-/
>
> Surprisingly, I think your first sentence *does* make something more
> clear. Let me check if I understand it right: when we call a method on
> super(Foo, self) it is as if we were calling call-next-method in
> Common Lisp or Dylan

I don't remember if CLOS was changed to use C3 Linearization also, but
the concept came from Dylan (http://www.webcom.com/haahr/dylan/
linearization-oopsla96.html) and that's what is implemented in Python.

[...]
> However, there's one piece that doesn't completely fit to the puzzle:
> why does getattr work? The help says:
>
> getattr(...)
>     getattr(object, name[, default]) -> value
>
>     Get a named attribute from an object; getattr(x, 'y') is
>     equivalent to x.y. When a default argument is given, it
>     is returned when the attribute doesn't exist; without it,
>     an exception is raised in that case.
>
> Does it work on the basis that "getattr(x, 'y') is equivalent to x.y"?
> What is then a "named attribute for an object" in Python? It seems not
> to be equivalent to the value of the item whose name is 'y' in the
> object's class __dict__...

Conceptually, x.y is always "get the y attribute of x" and the same as
getattr(x, 'y'). Depending on the type of x and y, and your
familiarity with Python internals, what actually happens during a
lookup might be surprising. In the vast majority of cases however, x.y
is equivalent to one of

  x.__dict__['y']
  type(x).__dict__['y']

but if you're a language geek like me, you might be excited that in
some cases it is

  type(x).__dict__['y'].__get__(x, type(x))

which says you get the value of x.y by calling y and passing x as an
argument -- if you know CLOS you'll recognize that it's a primitive
multi-method call. (there are some other special cases too, although
not as exciting ;-)

Much more detail can be found in Raymond's paper on descriptors
(http://users.rcn.com/python/download/Descriptor.htm) and Michele's
paper on super (http://www.phyast.pitt.edu/~micheles/python/
super.html).

-- bjorn





More information about the Python-list mailing list