Встроенный вызываемый
, упомянутый в других ответах, не отвечает на ваш вопрос в том виде, в каком он поставлен, потому что он также возвращает True
, помимо функций, для методов, классов, экземпляров классов, которые определяют метод __ call __
. Если заголовок и текст вашего вопроса неправильные, и вам все равно, является ли что-то на самом деле функцией, а только если оно вызываемое , тогда используйте эту встроенную функцию. Но лучший ответ на поставленный вопрос: импортируйте метод inspect
стандартной библиотеки Python и используйте inspect.isfunction .(Существуют и другие способы более низкой абстракции, но всегда рекомендуется использовать функциональные возможности модуля inspect
для самоанализа, когда он есть, вместо подходов более низкого уровня: inspect
помогает сохранить ваш код кратким, ясным, надежным и ориентированным на будущее).
Вы можете использовать inspect.isfunction (object)
. См.: docs.python.org
Тем не менее, вам следует избегать использования этого метода в повседневном коде. Иногда вам действительно нужно использовать отражение - например, платформе MVC может потребоваться загрузить класс и проверить его члены. Но обычно вы должны возвращать / передавать / иметь дело с объектами, имеющими такой же «интерфейс». Например, не возвращайте объект, который может быть целым числом или функцией - всегда возвращайте один и тот же «тип» объекта, чтобы ваш код был согласованным.
>>> import types
>>> def f(): pass
...
>>> x = 0
>>> type(f) == types.FunctionType
True
>>> type(x) == types.FunctionType
False
Это проверит, является ли это функцией. callable ()
проверит, является ли он вызываемым (то есть имеет метод __ call __
), поэтому он вернет true для класса, а также для функции или метода.
Философия использования различных объектов в программе на Python называется duck typing- если он выглядит как утка, крякает как утка и ходит как утка, то это утка. Объекты группируются не по их типу, а по тому, что они способны делать, и это распространяется даже на функции. При написании программы на Python вы всегда должны знать, что могут делать все ваши объекты, и использовать их без проверки.
Например, я могу определить функцию
def add_three(a, b c):
return a + b + c
и подразумевать, что она будет использоваться с тремя поплавками. Но, не проверяя это, я получаю гораздо более полезную функцию - я могу использовать ее с ints, с decimal.Decimals или, например, с fractions.Fractions.
То же самое относится и к наличию функции. Если я знаю, что у меня есть функция и хочу ее вызвать, я должен просто вызвать ее. Может быть, то, что у меня есть, это функция, а может быть, у меня есть другой вызываемый объект (например, связанный метод или экземпляр произвольного класса, который определяет __call__
), который может быть так же хорош. Не проверяя ничего, я делаю свой код способным работать с широким спектром обстоятельств, о которых я, возможно, даже не думал заранее.
В случае с callables я могу довольно надежно определить, есть ли у меня callables или нет, но ради простоты моего кода я не должен этого хотеть. Если кто-то передаст что-то, что не является вызываемым, вы все равно получите ошибку при вызове. Если я пишу код, который принимает параметр, который может быть вызываемым или нет, и я делаю разные вещи в зависимости от этого, похоже, что я должен улучшить свой API, определив две функции для выполнения этих двух разных вещей.
Если бы у вас действительно был способ обработать случай, когда вызывающая сторона передала что-то, что не является функцией (и это не было просто результатом безумного API), правильным решением было бы поймать TypeError
, который поднимается, когда вы пытаетесь вызвать что-то, что не может быть вызвано. В целом, лучше попытаться сделать что-то и восстановиться в случае неудачи, чем проверять заранее. (Вспомните клише: "Проще попросить прощения, чем разрешения"). Проверка на опережение может привести к неожиданным проблемам, основанным на тонких ошибках в логике, и может привести к условиям гонки.
Как вы думаете, зачем нужна проверка типов?
Используйте callable(boda)
, чтобы определить, является ли boda
вызываемым или нет.
Callable означает, что здесь есть функция, метод или даже класс. Но поскольку вы хотите различать только переменные и функции, это должно работать хорошо.
Тогда ваш код будет выглядеть так:
boda = len # boda is the length function now
if callable(boda):
print "Boda is a function!"
else:
print "Boda is not a function!"
Это не 100% идеальное решение, но вы можете проверить «вызываемую» встроенную функцию:
И что он должен вернуть для свойства , к которому вы обращаетесь как к атрибуту значения, но фактически вызывает функцию? Ваш, казалось бы, простой вопрос фактически открывает целую банку червей в Python. Это означает, что такие вещи, как callable
и isfunction
, полезны для вашего обучения и самоанализа, но, вероятно, вы не хотите полагаться на них при взаимодействии с другим кодом.
По касательной: см. Презентацию Turtles All The Way Down , чтобы узнать больше о том, как устроен Python.