Проверьте, является ли функция методом некоторого объекта - PullRequest
11 голосов
/ 11 мая 2011

Как проверить, является ли функция методом некоторого объекта?

Например:

def check_method(f):
    ...

check_method(lambda x: x + 1)           # >>> False
check_method(SomeClass().some_method)  # >>> True

В моем примере с helloworld есть несколько специальных атрибутов (например, «im_self», «__self__» и т. Д.). Можно ли на них положиться или есть какой-то более приятный способ?

Ответы [ 3 ]

18 голосов
/ 11 мая 2011

Использование inspect.ismethod().

В документации говорится:

Возвращать true, если объект является связанным методом, написанным на Python.

Это означает, что он будет работать так, как вы собираетесь для классов, которые вы определили в Python.Однако для методов встроенных классов, таких как list или классов, реализованных в модулях расширения, он вернет False.

4 голосов
/ 05 мая 2016

Можно также проверить соответствие типов, определенных во встроенной библиотеке типов :

import types
isinstance(obj.method, types.MethodType) # True
3 голосов
/ 12 октября 2011

Суть вопроса заключается в том, чтобы проверить, доступна ли какая-либо функция name в качестве метода.Поскольку типирование утки считается питоническим, должно быть простое

hasmethod(obj, 'some_method')

, но, похоже, нет.

Типизирование утки лучше всего сделать, просто попробовав:

try:
  obj.some_method()
except:
  # try something else

Если кто-то хочет, чтобы функция программно проверяла, есть ли у объекта метод с определенным именем переменной, то упоминалась следующая функция:

def hasmethod(obj, method_name):
  return hasattr(obj, method_name) and callable(getattr(obj, method_name))

Но для Python 3 и 3.1 как минимумвам нужно вернуть callable (), который был удален.Обсуждение необходимости вернуть его можно найти в записи об ошибке в Python Воскрешение с возможностью вызова, например:

def callable(obj):
    return isinstance(obj, collections.Callable) 

Это прямо из вышеупомянутого отслеживания ошибок Python.Другие источники в стеке упоминают

callable = lambda o: hasattr(o, '__call__') or isinstance(o, collections.Callable)

, который добавляет hasattr к вызову.Оба отлично работают в моем случае использования

>>> bstr = b'spam'
>>> str = 'eggs'
>>> hasmethod(str, 'decode')
False
>>> hasmethod(bstr, 'decode')
True

Для более подробной информации посмотрите на уже процитированный другой вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...