Reputation: 6063
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.
Upvotes: 4
Views: 2719
Reputation: 1121924
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.
Upvotes: 5
Reputation: 54
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.
Upvotes: 0
Reputation: 19329
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.
Upvotes: 0