[Python-Dev] Let's get rid of unbound methods (original) (raw)

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 >> mybase.themethod(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(mybase): def register(*args, **kws): mybase.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 .

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.



More information about the Python-Dev mailing list