Как вы проверяете, привязан ли метод python или нет?
-
09-06-2019 - |
Вопрос
Учитывая ссылку на метод, есть ли способ проверить, привязан ли метод к объекту или нет?Можете ли вы также получить доступ к экземпляру, к которому он привязан?
Решение
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.
Другие советы
В 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
я сам атрибут (только Python 2)