Как вы проверяете, привязан ли метод python или нет?

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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
39
0
12 073
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Ссылка не работает.

jjmontes 30.06.2017 00:27
Ответ принят как подходящий

def isbound(method):
    return method.im_self is not None

def instance(bounded_method):
    return bounded_method.im_self

Определяемые пользователем методы:

When a user-defined method object is created by retrieving a user-defined function object from a class, its im_self attribute is None and the method object is said to be unbound. When one is created by retrieving a user-defined function object from a class via one of its instances, its im_self attribute is the instance, and the method object is said to be bound. In either case, the new method's im_class attribute is the class from which the retrieval takes place, and its im_func attribute is the original function object.

В Python 2.6 и 3.0:

Instance method objects have new attributes for the object and function comprising the method; the new synonym for im_self is __self__, and im_func is also available as __func__. The old names are still supported in Python 2.6, but are gone in 3.0.

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

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

def is_bound(m):
    return hasattr(m, '__self__')

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

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

Ну, f на самом деле никогда не привязан к test_class, что здесь усложняется. Даже decorate не привязан (вы можете проверить, проверив test_class.test_method! = Decorate). Связанный метод создается из decorate, а который - это то, что присоединено к test_class. На самом деле вы пытаетесь выяснить, был ли связанный метод создан из определенной функции. Я не уверен, возможно ли это

Azmisov 24.09.2020 18:52

Решение, которое работает как для Python 2, так и для Python 3, непросто.

Используя пакет six, одним из решений может быть:

def is_bound_method(f):
    """Whether f is a bound method"""
    try:
        return six.get_method_self(f) is not None
    except AttributeError:
        return False

В Python 2:

  • Обычная функция не будет иметь атрибута im_self, поэтому six.get_method_self() вызовет AttributeError и вернет False.
  • Для несвязанного метода атрибут im_self будет установлен на None, поэтому он вернет False.
  • Связанный метод будет иметь атрибут im_self, установленный на значение, отличное от None, поэтому он вернет True.

В Python 3:

  • Обычная функция не будет иметь атрибута __self__, поэтому six.get_method_self() вызовет AttributeError и вернет False.
  • Несвязанный метод такой же, как и обычная функция, поэтому он вернет False.
  • У связанного метода будет установлен атрибут __self__ (не-None), поэтому он вернет True

Другие вопросы по теме