Нет, это невозможно, как вы и просили, потому что нет никакой внутренней разницы между связанными методами и функциями.Метод - это просто функция, обернутая, чтобы получить вызывающий экземпляр в качестве первого аргумента (используя Python дескрипторы ).
Подобный вызов:
Test.test_call
, который возвращаетнесвязанный метод, переводится как
Test.__dict__[ 'test_call' ].__get__( None, spam )
, который является несвязанным методом, даже если
Test.__dict__[ 'test_call' ]
является функцией.Это связано с тем, что функции являются дескрипторами, методы которых __get__
возвращают методы;когда Python видит один из них в цепочке поиска, он вызывает метод __get__
вместо продолжения вверх по цепочке.
По сути, «связанная методичность» функции определяется во время выполнения, а не при определении-time!
Декоратор просто видит функцию в том виде, как она определена, не просматривая ее в __dict__
, поэтому не может определить, смотрит ли он на связанный метод.
1024 * может быть возможно сделать с помощью декоратора классов, который модифицирует __getattribute__
, но это особенно неприятный хак.Почему у вас должен быть этот функционал?Конечно, поскольку вы должны поместить декоратор в функцию самостоятельно, вы можете передать ему аргумент, который говорит, определена ли указанная функция в классе?
class Test:
@decorate( method = True )
def test_call:
...
@decorate( method = False )
def test_call:
...