Problem:
Let us consider the following context:
class Call:
def __call__(self):
pass
class Foo:
def __init__(self):
self.var = Call()
def method(self):
pass
foo = Foo()
I mean, we have an object foo
which is an instance of Foo
, possessing a method method
and an attribute var
, who’s kind Call
(that is callable). By checking whether a method exists, we hope that only method
is returned as valid and var
nay.
Solution 1:
Spolier Alert: Do not use! :(
Proposed by Wallace in his reply (adapted):
def method_exists(instance, method):
return hasattr(instance, method) and callable(instance.method)
Testing for the problem:
>>> print(method_exists(foo, "method"))
True
>>> print(method_exists(foo, "var"))
True
See working on Ideone
That is, the solution failed in the second test.
Solution 2:
Spolier Alert: Do not use! :(
Proposed by me in a version prior to this reply:
def method_exists(instance, method):
return method in dir(instance) and callable(instance.method)
Testing for the problem:
>>> print(method_exists(foo, "method"))
True
>>> print(method_exists(foo, "var"))
True
See working on Ideone
That is, the solution too failed in the second test.
Solution 3:
Spolier Alert: It works! You can use :D
Also proposed by Wallace in his reply (adapted):
from inspect import ismethod
def method_exists(instance, method):
return hasattr(instance, method) and ismethod(getattr(instance, method))
Testing for the problem:
>>> print(method_exists(foo, "method"))
True
>>> print(method_exists(foo, "var"))
False
See working on Ideone
So you passed both tests.
Solution 3 required the inclusion of the getattr
for checking whether it is a method.
The answers to these questions will address all methods of the class. It was not my intention, I really wanted to know if a specific method exists or not, in the same way as in PHP with
method_exists('Class', 'method')
.– Wallace Maxters
@Virgilionovic sees my answer and maybe he’ll change his mind when the duplicate.
– Woss
@Virgilionovic no, return
True
for both. I kept it as solution 2 in my answer.– Woss
@Virgilionovic for attributes normal, works! The problem is when there is class composition and the attribute is an instance of a class
callable
. The test goes on to returnTrue
for this attribute without being a method.– Woss