В Python 2.6 или выше, рекомендуемый подход:
import collections
def is_func(instance, func):
return isinstance(getattr(instance, func, None), collections.Callable)
Новые ABC (абстрактные базовые классы) в модуле collections
являются правильным способом, в Python 2.6+ и 3.any, для выполнения такого рода «проверок типа утилитарной типизации» - гораздо более элегантных , несформированные и перспективные, чем более старые подходы, такие как callable
встроенный, operator.isCallable
, или проверка на наличие специальных специальных методов, таких как __call__
. Поскольку isinstance
теперь может быть перегружен, оставьте его на ABC, чтобы перегрузить его и выполнить проверки, заключив в капсулу любые подходы более низкого уровня, которые работают лучше всего!
Элегантность и преимущества нового подхода таковы, что, если вам нужно сделать свой код переносимым между старыми и новыми версиями Python, я рекомендую инкапсулировать «тесты на утку», которые вам требуются, в модуле, который может определить его функция зависит от sys.version
- использование isinstance(x, collections.Y)
в версии 2.6 или лучше, и более старых подходов, таких как hasattr(x, '__somespecialmethod__')
или callable(x)
в версии 2.5 или хуже.
Самое главное, и в более общем плане, не не загрязняет ваш новый основной код приложения старыми, низшими способами - если требования обратной переносимости вынуждают вашу общую систему иметь некоторый «мусор» ( чтобы продолжать работать на старых версиях Python), по крайней мере, прилично спрятать этот мусор в его собственном «отсеке» (где однажды вы сможете легко смести его, если позволяют ограничения развертывания вашего приложения! -).