Going from a bound instance method to its class instance in Python

March 17, 2019

In response to yesterday's entry on how I feel callable classes are better than closures, a commentator suggested:

If you need something callable, why not use a bound method? They have a reference to the parent too.

This raises a question: how easy and reliable is it to go from a bound method on an instance to the instance itself?

In both Python 2 and Python 3, a bound method is an instance of a special type (how this happens is described in my entry on how functions become bound methods). Although the Python 3 documentation is not explicit about it, this type is what is described in the "Instance methods" section of the Python 3 data model. This description of the (bound) method type officially documents the __self__ attribute, which is a reference to the original instance that the bound method is derived from. So the answer is that given an object x that is passed to you as a bound method, you can recover the actual instance as x.__self__ and then inspect it from there.

(In Python 2.7, there is also the im_self attribute, which contains the same information.)

If you want your code to check if it has a bound method, you can use isinstance() with types.MethodType. This name for the type can also be used to check its help(), which really won't tell you much; you're better off reading the "Instance methods" section of the data model.

I'm not sure how I feel about relying on this. On the one hand, it is officially documented and it works the same in Python 3 and Python 2 (ignoring Python 2's im_self and the possibility of unbound methods on Python 2). On the other hand, this is a __ attribute, and using those generally feels somewhat like I'm peeking into implementation details. I don't know if the Python developers consider this a stable API or something that very definitely isn't guaranteed over the long term.

(If nothing else, now I know a little bit more about Python than I did before I decided to look this up. I was actually expecting the answer to be more obscure than it turned out to be.)

Written on 17 March 2019.
« Callable class instances versus closures in Python
Prometheus subqueries pick time points in a surprising way »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Mar 17 23:57:39 2019
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.