thebjorn
1/13/2008 2:32:00 PM
On Jan 13, 1:51 pm, Richard Szopa <ryszard.sz...@gmail.com> wrote:
> On Jan 13, 8:59 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net> wrote:
>
> > On Sat, 12 Jan 2008 14:23:52 -0800, Richard Szopa wrote:
> > > However, I am very surprised to learn that
>
> > > super_object.__getattr__(name)(*args, **kwargs)
>
> > > getattr(super_object, name)(*args, **kwargs)
>
> > > are not equivalent. This is quite odd, at least when with len()
> > > and .__len__, str() and .__str__. Do you maybe know what's the
> > > rationale behind not following that convention by getattr?
>
> > I think you are confusing `__getattr__` and `__getattribute__` here!
> > `getattr()` maps to `__getattr__()`, it's `__getattribute__` that's
> > different.
>
> Well, in my code calling super_object.__getattr__(name)(*args,
> **kwargs) and getattr(super_object, name)(*args, **kwargs) gives
> *different* effects (namely, the latter works, while the former
> doesn't). That kinda suggests that they don't map to each other :-).
> And that makes me feel confused.
>
> Cheers,
>
> -- Richard
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 :-/
super(..) is designed to handle situations like this correctly
class Root(object):
n = 1
class Left(Root):
def foo(self):
print 'n =', self.n
print 'super n = ', super(Left, self).n
class Right(Root):
n = 2
class Leaf(Left,Right):
n = 3
x = Leaf()
x.foo()
the correct output is
n = 3
super n = 2
-- bjorn