Проверьте, определена ли функция в классе Python.

Как правильно в Python 3.7+ проверить, определена ли функция в классе Python. Пример:

class A:

    def fun1(self):
        pass

def fun2():
    pass

Я хотел бы отметить, что A.fun1 был определен внутри класса, а fun2 - нет.


person Hernan    schedule 22.02.2021    source источник
comment
Вы спрашиваете, что magic(A.fun1) должно вернуть True, а magic(fun2) должно вернуть False, верно?   -  person deceze♦    schedule 22.02.2021
comment
какой смысл это делать? Какую проблему ты пытаешься решить?   -  person marcusshep    schedule 22.02.2021
comment
Существуют inspect.ismethod и inspect.isfunction. ismethod следует вызывать для объекта. Сделайте это: print(inspect.ismethod(A().fun1), inspect.isfunction(A().fun1)); print(inspect.ismethod(fun2), inspect.isfunction(fun2)).   -  person Arty    schedule 22.02.2021
comment
@deceze Точно   -  person Hernan    schedule 22.02.2021
comment
@Arty Как вы указали, этот метод требует создания экземпляра класса, что может быть невозможно или просто или иметь побочные эффекты в некоторых случаях.   -  person Hernan    schedule 22.02.2021
comment
@marcusshep Я хочу по-разному модифицировать вызываемый объект при работе со статическими методами, методами класса, методами или функциями. Прямо сейчас у меня есть четыре разных декоратора, но с точки зрения пользователя было бы проще иметь один декоратор, который отправляет нужную реализацию в зависимости от цели. Когда я попытался это реализовать, мне не удалось найти надежный способ получить эту информацию для неустановленного класса.   -  person Hernan    schedule 22.02.2021


Ответы (2)


Вы можете использовать атрибут __qualname__ (определен в PEP 3155) и проверьте, содержит ли он ., указывающий, что этот объект был определен в вложенная область. Обратите внимание, что это также относится к функциям, определенным внутри других функций, поэтому в этом смысле это может дать вам ложные срабатывания.

>>> def test(): ...
... 
>>> test.__qualname__
'test'
>>> class Foo:
...     def test(self): ...
... 
>>> Foo.test.__qualname__
'Foo.test'
>>> def f():
...     def g(): ...
...     return g
... 
>>> f().__qualname__
'f.<locals>.g'
person a_guest    schedule 22.02.2021

Вот вам hasattr()

>>> hasattr(A, 'fun1')
>>> True

>>> hasattr(A, 'fun2')
>>> False
person go2nirvana    schedule 22.02.2021
comment
OP хочет проверить, является ли это методом класса или функцией, а не тем, что у класса есть метод - person python_user; 22.02.2021
comment
И как мой ответ не решает эту проблему? - person go2nirvana; 22.02.2021
comment
метод не является функцией, и ваш также будет работать для обычного атрибута - person python_user; 22.02.2021
comment
Метод — это функция, определенная внутри класса. Определение того, имеет ли класс определенную функцию, в точности равнозначно различению того, что функция была определена внутри класса - в соответствии с запросом OP. - person go2nirvana; 22.02.2021
comment
посмотрите на комментарий deceze, это в значительной степени то, чего хочет ОП - person python_user; 22.02.2021
comment
Что ж, я отвечаю на то, что было задано в вопросе, а не играю в догадки, что это на самом деле означает. - person go2nirvana; 22.02.2021
comment
отвечать на вопрос, не зная, что означает OP, не очень продуктивно, можно использовать комментарии, чтобы уточнить - person python_user; 22.02.2021
comment
В данном конкретном случае вопрос был для меня предельно ясен, поэтому не вижу необходимости уточнять. На самом деле, если вы посмотрите на ответ на предложение deceze: третий ответ (и 2-й по количеству голосов) такой же, как у меня. Из этого я делаю вывод, что вопросы на самом деле похожи. И вместо того, чтобы сомневаться в моем ответе, правильным действием было бы пометить вопрос как дубликат. В любом случае, я предлагаю двигаться дальше. - person go2nirvana; 22.02.2021
comment
@ go2nirvana Я думал, что последняя фраза в моем вопросе проясняет это: я хотел бы различать, что A.fun1 был определен в классе, а fun2 — нет. Что не то же самое, что сказать, что данный класс определяет функцию с заданным название. - person Hernan; 22.02.2021
comment
@Hernan stackoverflow.com/questions/961048/ - person go2nirvana; 23.02.2021