<br><div><span class="gmail_quote">On 4/19/06, <b class="gmail_sendername">Guido van Rossum</b> <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>> >Oh, I believe super() also supports static and/or class methods. I'm<br>> >not sure how to handle this but I'm sure you can think of something.<br>><br>> If super.foobar(args) -> super(ThisClass,firstarg).foobar(args), then it
<br>> will Just Work(TM) for class methods, since their first argument is the<br>> class, and super(someclass,myclass).aClassMethod(...) is the normal way of<br>> invoking a superclass classmethod.<br><br>But how about static methods? Inside a static method, I believe you're
<br>allowed to write<br><br> super(ThisClass).foobar(args)<br><br>which would call<br><br> ThisClass.__base__.foobar(args)<br><br>(assuming single inheritance for a moment) i.e. nothing is added to<br>the argument list.
</blockquote><div><br>That's not how it works (and that's good; refusing the temptation to guess, and what not :) super() cannot make any assumptions about the next class in the MRO, and since you don't *have* a class in a staticmethod, it has no way to find out. staticmethods just can't sensibly call 'their baseclass method' (unless they're really just "explicit classmethods", like __new__, but those best be real classmethods (even __new__ :))
<br><br>Currently, super(ThisClass) returns an 'unbound super object', which is not a proxy for 'the next class' but rather an descriptor that would get the right proxy object upon retrieval:<br><br>>>> class X(object):
<br>... @staticmethod<br>... def static(*args):<br>... print "X.static%r" % (args,)<br>... <br>>>> class Y(X):<br>... @staticmethod<br>... def static(*args):<br>... print "
Y.static%r" % (args,)<br>... super(Y).static(*args) <br>... <br>>>> Y.static()<br>Y.static()<br>Traceback (most recent call last):<br> File "<stdin>", line 1, in ?<br> File "<stdin>", line 5, in static
<br>AttributeError: 'super' object has no attribute 'static'<br>>>> y = Y()<br>>>> y.static()<br>Y.static()<br>Traceback (most recent call last):<br> File "<stdin>", line 1, in ?<br> File "<stdin>", line 5, in static
<br>AttributeError: 'super' object has no attribute 'static'<br><br>And to prove it's a descriptor:<br>>>> class Z(X):<br>... @staticmethod<br>... def static(*args):<br>... print "Z.static%r" % (args,)
<br>... super(Z).__get__(Z, None).static(*args)<br>... <br>>>> Z.static()<br>Z.static()<br>X.static()<br>>>> Z().static()<br>Z.static()<br>X.static()<br><br>Doing super(Z).__get__(Z, None).static is just as static as calling
X.static, though (with the only difference being that you name Z multiple times, instead of naming X multiple times.) It doesn't take MI into account at all.<br></div><br>And yes, staticmethods are damned near useless. Let's not worry about them calling their baseclass methods -- they honestly shouldn't.
<br></div><br>-- <br>Thomas Wouters <<a href="mailto:thomas@python.org">thomas@python.org</a>><br><br>Hi! I'm a .signature virus! copy me into your .signature file to help me spread!