In Python 2.6 or better, the recommended approach is:
import collections
def is_func(instance, func):
return isinstance(getattr(instance, func, None), collections.Callable)
The new ABCs (Abstract Base Classes) in the collections
module are the correct way, in Python 2.6+ and 3.any, to perform this kind of "duck-typing-like type checks" -- much more elegant, unform, and future-proof than older approaches such as the callable
built-in, operator.isCallable
, or checking for the presence of specific special methods such as __call__
. Since isinstance
can now be overloaded, leave it up to the ABCs to overload it and perform the checks by encapsulating whatever lower-level approaches work best!
The elegance and advantages of the new approach are such that, if you need to make your code portable between older and newer versions of Python, I recommend encapsulating the "duck-typing tests" that you require in a module that can define its function depending on the sys.version
-- using isinstance(x, collections.Y)
in 2.6 or better, and older approaches such as hasattr(x, '__somespecialmethod__')
or callable(x)
in 2.5 or worse.
Most importantly, and more generally, don't pollute your new, mainline application code with the old, inferior ways -- if backwards-portability requirements force your overall system to have some "garbage" (in order to keep running on old Python versions), at least hide that garbage decently in its own "compartment" (where one day you may be able to easily sweep it away if your app's deployment constraints permit!-).