Comprobar si una función es un método de algún objeto.

¿Cómo comprobar si una función es un método de algún objeto?

Por ejemplo:

def check_method(f): ... check_method(lambda x: x + 1) # >>> False check_method(SomeClass().some_method) # >>> True 

Hay algunos atributos especiales en los métodos en mi ejemplo ‘helloworld’ (por ejemplo, ‘im_self’, ‘__self__’ etc). ¿Puedo confiar en ellos o hay alguna manera mejor?

Utilice inspect.ismethod() .

La documentación establece:

Devuelve verdadero si el objeto es un método enlazado escrito en Python.

Esto significa que funcionará como pretende para las clases que defina en Python. Sin embargo, para los métodos de clases incorporadas como list o clases implementadas en módulos de extensión, devolverá False .

También es posible verificar los tipos definidos en la biblioteca de tipos incorporada:

 import types isinstance(obj.method, types.MethodType) # True 

Un giro a la pregunta implica preguntar si algún nombre de función estaría disponible como método. Dado que la tipificación de pato se considera pythonica, debe haber un simple

 hasmethod(obj, 'some_method') 

Pero parece que no hay.

La tipificación de pato parece ser mejor si se intenta:

 try: obj.some_method() except: # try something else 

Si alguien quiere que una función verifique mediante progtwigción si un objeto tiene un método con un determinado nombre de variable, se mencionó la siguiente función:

 def hasmethod(obj, method_name): return hasattr(obj, method_name) and callable(getattr(obj, method_name)) 

Pero para Python 3 y 3.1, al menos, necesita recuperar Callable () que se eliminó. Se puede encontrar una discusión sobre la necesidad de recuperarla en una entrada de Python bug Resurrect callable con, por ejemplo:

 def callable(obj): return isinstance(obj, collections.Callable) 

Esto es directamente desde el mencionado pittracker de python. Otras fonts en stackoverflow mencionan

 callable = lambda o: hasattr(o, '__call__') or isinstance(o, collections.Callable) 

que añade el hasattr a la llamada. Ambos funcionan bien en mi caso de uso

 >>> bstr = b'spam' >>> str = 'eggs' >>> hasmethod(str, 'decode') False >>> hasmethod(bstr, 'decode') True 

Para más detalles mira la otra pregunta ya citada.