[Python-Dev] Let's get rid of unbound methods

Tim Peters tim.peters at gmail.com
Wed Jan 5 03:07:31 CET 2005


[Tim Peters]
>> ...  Unbound methods are used most often (IME) to call a
>> base-class method from a subclass, like
>> my_base.the_method(self, ...).
>>  It's especially easy to forget to write `self, ` there, and the
>> exception msg then is quite focused because of that extra bit of
>> type checking.  Otherwise I expect we'd see a more-mysterious
>> AttributeError or TypeError when the base method got around to
>> trying to do something with the bogus `self` passed to it.

[Josiah Carlson]
> Agreed.

Well, it's not that easy to agree with.  Guido replied that most such
cases would raise an argument-count-mismatch exception instead.  I
expect that's because he stopped working on Zope code, so actually
thinks it's odd again to see a gazillion methods like:

class Registerer(my_base):
    def register(*args, **kws):
        my_base.register(*args, **kws)

I bet he even presumes that if you chase such chains long enough,
you'll eventually find a register() method *somewhere* that actually
uses its arguments <wink>.

> While it seems that super() is the 'modern pradigm' for this,
> I have been using base.method(self, ...) for years now, and have
> been quite happy with it.  After attempting to convert my code to
> use the super() paradigm, and having difficulty, I discovered James
> Knight's "Python's Super Considered Harmful" (available at
> http://www.ai.mit.edu/people/jknight/super-harmful/ ), wherein I
> discovered how super really worked (I should have read the
> documention in the first place), and reverted my changes to the
> base.method version.

How did super() get into this discussion?  I don't think I've ever
used it myself, but I avoid fancy inheritance graphs in "my own" code,
so can live with anything.

> I could live with it too, but I would probably use an equivalent of the
> following (with actual type checking):
>
> def mysuper(typ, obj):
>    lm = list(o.__class__.__mro__)
>    indx = lm.index(typ)
>    if indx == 0:
>        return obj
>    return super(lm[indx-1], obj)
>
> All in all, I'm -0.  I don't desire to replace all of my base.method
> with mysuper(base, obj).method, but if I must sacrifice
> convenience for the sake of making Python 2.5's implementation
> simpler, I guess I'll deal with it. My familiarity with grep's regular
> expressions leaves something to be desired, so I don't know how
> often base.method(self,...) is or is not used in the standard library.

I think there may be a misunderstanding here.  Guido isn't proposing
that base.method(self, ...) would stop working -- it would still work
fine.  The result of base.method would still be a callable object:  it
would no longer be of an "unbound method" type (it would just be a
function), and wouldn't do special checking on the first argument
passed to it anymore, but base.method(self, ...) would still invoke
the base class method.  You wouldn't need to rewrite anything (unless
you're doing heavy-magic introspection, picking callables apart).


More information about the Python-Dev mailing list