Я пишу Python, который нацелен на версии 3.2 и выше. Похоже, что использование встроенной функции, вызываемой, является наиболее простым и эффективным способом для этого. Я видел рекомендации для hasattr(x, "__call__")
, collections.Callable(x)
и просто использовал try/except
вокруг попытки вызова.Использование callable (x) vs. hasattr (x, "__call__")
Я тестировал элементы, которые можно назвать (класс и функция), используя timeit
с 100 000 итерациями; в обоих случаях использование вызываемого объекта занимает всего около 75% времени проверки атрибута. Когда элемент не может быть вызван (целое число и строка) с использованием вызываемых остатков с той же стоимостью, что и класс или функция, при проверке атрибута примерно в 2,3 раза дороже, чем для класса или функции. Я не ожидал этой разницы, но это также способствует четкому и кратким подходам callable(x)
.
Но я относительно новичок в Python и не эксперт, поэтому есть причины, по которым я не знаю, что я должен использовать подход hasattr или другой подход?
FWIW, результаты различных сроков следуют. Первый символ - это просто t для timeit, второй - тип тестируемого объекта (c = class, f = function, i = integer, s = string), а остальное указывает метод (attr - check attribute, call - use callable, try - используйте try/except).
tcattr 0.03665385400199739 tccall 0.026238360142997408 tctry 0.09736267629614304 tfattr 0.03624538065832894 tfcall 0.026362861895904643 tftry 0.032501874250556284 tiattr 0.08297350149314298 ticall 0.025826044152381655 titry 0.10657657453430147 tsattr 0.0840187013927789 tscall 0.02585409547373274 tstry 0.10742772077628615
sidenote: вызываемый был удален в python3.0 (http://www.python.org/dev/peps/pep-3100/#built-in-namespace) и - заметив, что это [было плохо выбор] (http://bugs.python.org/issue10518) - [приведен в 3.2] (http://docs.python.org/3.2/library/functions.html?highlight=callable#callable) – mata