Given a reference to a method, is there a way to check whether the method is bound to an object or not? Can you also access the instance that it's bound to?
5 Answers
def isbound(method):
return method.im_self is not None
def instance(bounded_method):
return bounded_method.im_self
When a user-defined method object is created by retrieving a user-defined function object from a class, its
im_self
attribute isNone
and the method object is said to be unbound. When one is created by retrieving a user-defined function object from a class via one of its instances, itsim_self
attribute is the instance, and the method object is said to be bound. In either case, the new method'sim_class
attribute is the class from which the retrieval takes place, and itsim_func
attribute is the original function object.
In Python 2.6 and 3.0:
Instance method objects have new attributes for the object and function comprising the method; the new synonym for
im_self
is__self__
, andim_func
is also available as__func__
. The old names are still supported in Python 2.6, but are gone in 3.0.

- 1,540
- 11
- 16

- 399,953
- 195
- 994
- 1,670
In python 3 the __self__
attribute is only set on bound methods. It's not set to None
on plain functions (or unbound methods, which are just plain functions in python 3).
Use something like this:
def is_bound(m):
return hasattr(m, '__self__')

- 12,337
- 5
- 48
- 63
-
There are plain functions that have the `__self__` attribute set, e.g. the built-in function `sum`. – kadee Oct 04 '22 at 13:36
The chosen answer is valid in almost all cases. However when checking if a method is bound in a decorator using chosen answer, the check will fail. Consider this example decorator and method:
def my_decorator(*decorator_args, **decorator_kwargs):
def decorate(f):
print(hasattr(f, '__self__'))
@wraps(f)
def wrap(*args, **kwargs):
return f(*args, **kwargs)
return wrap
return decorate
class test_class(object):
@my_decorator()
def test_method(self, *some_params):
pass
The print
statement in decorator will print False
.
In this case I can't find any other way but to check function parameters using their argument names and look for one named self
. This is also not guarantied to work flawlessly because the first argument of a method is not forced to be named self
and can have any other name.
import inspect
def is_bounded(function):
params = inspect.signature(function).parameters
return params.get('self', None) is not None

- 2,460
- 1
- 21
- 23
-
2Well `f` is never actually bound to `test_class` which is the complication here. Even `decorate` is not bound either (you can verify by checking test_class.test_method != decorate). A bound method is created from `decorate` and *that* is what is attached to `test_class`. What you are really trying to find is whether a bound method has been created from a specific function. I'm not sure if that is possible – Azmisov Sep 24 '20 at 15:52
-
I think this is the only way to know if the given function expects to receive the insance or or not. – Anr Jan 18 '22 at 10:45
-
1import inspect; expectself = next(iter(inspect.signature(function))) == 'self' – Anr Jan 18 '22 at 10:59
-
I agree that this is impossible. I've attempted through [this method](https://stackoverflow.com/a/25959545/308451) and even [this](https://stackoverflow.com/a/54316392/308451). The latter _almost_ works, until a second (unrelated) decorator is added before your decorator. The next best thing I can come up with truly is simply checking for `"self"` (and/or `"cls"`)... – JBSnorro Aug 13 '22 at 06:25
-
1What happens here is that functions in classes are normal, unbound. When creating an instance (when ``__new__`` is called), bound methods are created for those functions and populate new instance. So, there is no way that a normal function in class is bound, because it isn't and decorators are "applied" just after function creation (and therefore before class creation), so there isn't even any object that such function could be applied to. ``@classmethod`` uses a trick named "```__get__``` magic method". – oBrstisf8o Jan 17 '23 at 21:08
A solution that works for both Python 2 and 3 is tricky.
Using the package six
, one solution could be:
def is_bound_method(f):
"""Whether f is a bound method"""
try:
return six.get_method_self(f) is not None
except AttributeError:
return False
In Python 2:
- A regular function won't have the
im_self
attribute sosix.get_method_self()
will raise anAttributeError
and this will returnFalse
- An unbound method will have the
im_self
attribute set toNone
so this will returnFalse
- An bound method will have the
im_self
attribute set to non-None
so this will returnTrue
In Python 3:
- A regular function won't have the
__self__
attribute sosix.get_method_self()
will raise anAttributeError
and this will returnFalse
- An unbound method is the same as a regular function so this will return
False
- An bound method will have the
__self__
attribute set (to non-None
) so this will returnTrue

- 2,838
- 1
- 22
- 50