Как определить, является ли переменная функцией в Python? [дубликат]

7
задан N.N. 20 February 2013 в 10:24
поделиться

8 ответов

Встроенный вызываемый , упомянутый в других ответах, не отвечает на ваш вопрос в том виде, в каком он поставлен, потому что он также возвращает True , помимо функций, для методов, классов, экземпляров классов, которые определяют метод __ call __ . Если заголовок и текст вашего вопроса неправильные, и вам все равно, является ли что-то на самом деле функцией, а только если оно вызываемое , тогда используйте эту встроенную функцию. Но лучший ответ на поставленный вопрос: импортируйте метод inspect стандартной библиотеки Python и используйте inspect.isfunction .(Существуют и другие способы более низкой абстракции, но всегда рекомендуется использовать функциональные возможности модуля inspect для самоанализа, когда он есть, вместо подходов более низкого уровня: inspect помогает сохранить ваш код кратким, ясным, надежным и ориентированным на будущее).

13
ответ дан 6 December 2019 в 05:03
поделиться

Вы можете использовать inspect.isfunction (object) . См.: docs.python.org

Тем не менее, вам следует избегать использования этого метода в повседневном коде. Иногда вам действительно нужно использовать отражение - например, платформе MVC может потребоваться загрузить класс и проверить его члены. Но обычно вы должны возвращать / передавать / иметь дело с объектами, имеющими такой же «интерфейс». Например, не возвращайте объект, который может быть целым числом или функцией - всегда возвращайте один и тот же «тип» объекта, чтобы ваш код был согласованным.

12
ответ дан 6 December 2019 в 05:03
поделиться
>>> import types
>>> def f(): pass
...
>>> x = 0
>>> type(f) == types.FunctionType
True
>>> type(x) == types.FunctionType
False

Это проверит, является ли это функцией. callable () проверит, является ли он вызываемым (то есть имеет метод __ call __ ), поэтому он вернет true для класса, а также для функции или метода.

2
ответ дан 6 December 2019 в 05:03
поделиться

Философия использования различных объектов в программе на 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, который поднимается, когда вы пытаетесь вызвать что-то, что не может быть вызвано. В целом, лучше попытаться сделать что-то и восстановиться в случае неудачи, чем проверять заранее. (Вспомните клише: "Проще попросить прощения, чем разрешения"). Проверка на опережение может привести к неожиданным проблемам, основанным на тонких ошибках в логике, и может привести к условиям гонки.

Как вы думаете, зачем нужна проверка типов?

1
ответ дан 6 December 2019 в 05:03
поделиться

Используйте 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!"
4
ответ дан 6 December 2019 в 05:03
поделиться

В python есть вызываемая функция.

 if callable(boda):
7
ответ дан 6 December 2019 в 05:03
поделиться

Это не 100% идеальное решение, но вы можете проверить «вызываемую» встроенную функцию:

http://docs.python.org/library/functions.html

1
ответ дан 6 December 2019 в 05:03
поделиться

И что он должен вернуть для свойства , к которому вы обращаетесь как к атрибуту значения, но фактически вызывает функцию? Ваш, казалось бы, простой вопрос фактически открывает целую банку червей в Python. Это означает, что такие вещи, как callable и isfunction , полезны для вашего обучения и самоанализа, но, вероятно, вы не хотите полагаться на них при взаимодействии с другим кодом.

По касательной: см. Презентацию Turtles All The Way Down , чтобы узнать больше о том, как устроен Python.

0
ответ дан 6 December 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: