Going from a bound instance method to its class instance in Python
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.)
|
|