4

Given a class C with a function or method f, I use inspect.ismethod(obj.f) (where obj is an instance of C) to find out if f is bound method or not. Is there a way to do the same directly at the class level (without creating an object)?

inspect.ismethod does not work as this:

class C(object):

    @staticmethod
    def st(x):
        pass

    def me(self):
        pass

obj = C()

results in this (in Python 3):

>>> inspect.ismethod(C.st) 
False
>>> inspect.ismethod(C.me)
False
>>> inspect.ismethod(obj.st) 
False
>>> inspect.ismethod(obj.me)
True

I guess I need to check if the function/method is member of a class and not static but I was not able to do it easily. I guess it could be done using classify_class_attrs as shown here How would you determine where each property and method of a Python class is defined? but I was hoping there was another more direct way.

3 Answers 3

5

There are no unbound methods in Python 3, so you cannot detect them either. All you have is regular functions. At most you can see if they have a qualified name with a dot, indicating that they are nested, and their first argument name is self:

if '.' in method.__qualname__ and inspect.getargspec(method).args[0] == 'self':
    # regular method. *Probably*

This of course fails entirely for static methods and nested functions that happen to have self as a first argument, as well as regular methods that do not use self as a first argument (flying in the face of convention).

For static methods and class methods, you'd have to look at the class dictionary instead:

>>> isinstance(vars(C)['st'], staticmethod)
True

That's because C.__dict__['st'] is the actual staticmethod instance, before binding to the class.

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

Comments

0

Could you use inspect.isroutine(...)? Running it with your class C I get:

>>> inspect.isroutine(C.st)
True
>>> inspect.isroutine(C.me)
True
>>> inspect.isroutine(obj.st)
True
>>> inspect.isroutine(obj.me)
True

Combining the results of inspect.isroutine(...) with the results of inspect.ismethod(...) may enable you to infer what you need to know.

Edit: dm03514's answer suggests you might also try inspect.isfunction():

>>> inspect.isfunction(obj.me)
False
>>> inspect.isfunction(obj.st)
True
>>> inspect.isfunction(C.st)
True
>>> inspect.isfunction(C.me)
False

Though as Hernan has pointed out, the results of inspect.isfunction(...) change in python 3.

Comments

0

Since inspect.ismethod returns True for both bound and unbound methods in Python 2.7 (ie., is broken), I'm using:

def is_bound_method(obj):
    return hasattr(obj, '__self__') and obj.__self__ is not None

It also works for methods of classes implemented in C, e.g., int:

>>> a = 1
>>> is_bound_method(a.__add__)
True
>>> is_bound_method(int.__add__)
False

But is not very useful in that case because inspect.getargspec does not work for functions implemented in C.

is_bound_method works unchanged in Python 3, but in Python 3, inspect.ismethod properly distinguishes between bound and unbound methods, so it is not necessary.

1 Comment

This is only useful for Python two, while the question specifically asks about Python three, where there are no unbound methods.

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.