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

Josiah Carlson jcarlson at uci.edu
Wed Jan 5 07:28:37 CET 2005


Tim Peters <tim.peters at gmail.com> wrote:
> 
> [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>.

If type checking is important, one can always add it using decorators. 
Then again, I would be willing to wager that most people wouldn't add it
due to laziness, until it bites them for more than a few hours worth of
debugging time.


> > 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.

It was my misunderstanding of your statement in regards to base.method. 
I had thought that base.method(self, ...) would stop working, and
attempted to discover how one would be able to get the equivalent back,
regardless of the inheritance graph.


> > 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).

Indeed, there was a misunderstanding on my part.  I misunderstood your
discussion of base.method(self, ...) to mean that such things would stop
working.  My apologies.


 - Josiah



More information about the Python-Dev mailing list