Как вы проверяете, связан ли метод python или нет? - PullRequest
32 голосов
/ 10 сентября 2008

Учитывая ссылку на метод, есть ли способ проверить, привязан ли метод к объекту или нет? Вы также можете получить доступ к экземпляру, к которому он привязан?

Ответы [ 4 ]

38 голосов
/ 10 сентября 2008
def isbound(method):
    return method.im_self is not None

def instance(bounded_method):
    return bounded_method.im_self

Пользовательские методы:

Когда пользовательский объект метода созданный путем извлечения пользовательского функциональный объект из класса, его im_self атрибут None и Объект метода называется несвязанным. Когда один создается путем извлечения пользовательский функциональный объект из класс через один из его экземпляров, его im_self атрибут является экземпляром, и объект метода называется связанным. В любом случае, новый метод im_class атрибут является классом из который происходит, и его im_func атрибут является оригиналом функциональный объект.

В Python 2,6 и 3,0 :

Объекты метода экземпляров имеют новые атрибуты для объекта и функции включающий метод; новый синоним для im_self есть __self__ и im_func также доступен как __func__. Старый имена все еще поддерживаются в Python 2.6, но ушли в 3.0.

16 голосов
/ 23 сентября 2013

В питоне 3 атрибут __self__ только установлен для связанных методов. Он не установлен на None для простых функций (или несвязанных методов, которые являются простыми функциями в Python 3).

Используйте что-то вроде этого:

def is_bound(m):
    return hasattr(m, '__self__')
4 голосов
/ 28 апреля 2018

Выбранный ответ действителен практически во всех случаях. Однако при проверке, связан ли метод в декораторе с использованием выбранного ответа, проверка завершится неудачно. Рассмотрим этот пример декоратора и метод:

def my_decorator(*decorator_args, **decorator_kwargs):
    def decorate(f):
        print(hasattr(f, '__self__'))
        @wraps(f)
        def wrap(*args, **kwargs):
            return f(*args, **kwargs)
        return wrap
    return decorate

class test_class(object):
    @my_decorator()
    def test_method(self, *some_params):
        pass

Оператор print в декораторе выведет False. В этом случае я не могу найти какой-либо другой способ, кроме как проверить параметры функции, используя их имена аргументов и найти один с именем self. Это также не гарантирует безупречную работу, поскольку первый аргумент метода не обязательно должен называться self и может иметь любое другое имя.

import inspect

def is_bounded(function):
    params = inspect.signature(function).parameters
    return params.get('self', None) is not None
3 голосов
/ 10 сентября 2008

im_self атрибут (только Python 2)

...