22

How to check if a function is a method of some object?

For example:

def check_method(f):
    ...

check_method(lambda x: x + 1)           # >>> False
check_method(SomeClass().some_method)  # >>> True

There are some special attributes in methods in my 'helloworld' example (e.g. 'im_self', '__self__' etc). Can I rely on them or there is some nicer way?

3 Answers 3

28

Use inspect.ismethod().

The documentation states:

Return true if the object is a bound method written in Python.

This means that it will work as you intend for classes that you define in Python. However, for methods of built-in classes like list or classes implemented in extension modules it will return False.

Sign up to request clarification or add additional context in comments.

1 Comment

Note that you must pass in a method of an instance for this and types.MethodType to work. Not method of the class. For example: SomeClass.some_method will evaluate to False. And during the definition of the class, this is not possible.
8

It is also possible to check against the types defined in the built in types library:

import types
isinstance(obj.method, types.MethodType) # True

1 Comment

Note: this only works in py3 for bound methods, since in py3 there is no such thing as an unbound method anymore, it will just be a function. It does work in py2 for both cases however.
3

A twist to the question involves asking to check if some function name would be available as a method. Since duck typing is considered pythonic there should be a simple

hasmethod(obj, 'some_method')

but it seems, there isn't.

Duck typing seems to be best done by just trying:

try:
  obj.some_method()
except:
  # try something else

If someone wants a function to check programmatically if an object has a method with a certain variable name, then the following function has been mentioned:

def hasmethod(obj, method_name):
  return hasattr(obj, method_name) and callable(getattr(obj, method_name))

But for Python 3 and 3.1 at least you need to get callable() back which was removed. A discussion of the want of bringing it back can be found in a python bug entry Resurrect callable with e.g.:

def callable(obj):
    return isinstance(obj, collections.Callable) 

This is straight from the above mentioned python bugtracker. Other sources on stackoverflow mention

callable = lambda o: hasattr(o, '__call__') or isinstance(o, collections.Callable)

which adds the hasattr to the call. Both work fine in my use case

>>> bstr = b'spam'
>>> str = 'eggs'
>>> hasmethod(str, 'decode')
False
>>> hasmethod(bstr, 'decode')
True

For more details look at the already cited other question

1 Comment

The righter way to resurrect callable in Python 3.0 and 3.1 was to access the underlying function through ctypes: bool(ctypes.pythonapi.PyCallable_Check(ctypes.py_object(obj))). Incidentally I made a Python library years ago to do that: pypi.org/project/ctypes-callable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.