2009-08-11 14 views
26

¿Cómo se puede verificar si una variable es un método de instancia o no? Estoy usando Python 2.5.Python: ¿Afirmar que la variable es el método de instancia?

Algo como esto:

class Test: 
    def method(self): 
     pass 

assert is_instance_method(Test().method) 
+16

¿Qué hay de malo en preguntar aquí? – quano

+3

Leer la fuente no sirve de nada, presumiblemente está escribiendo algún código que necesita saber la respuesta en tiempo de ejecución. Posiblemente iterando a través de todos los atributos de un objeto, por ejemplo. –

Respuesta

41

inspect.ismethod es lo que quiere saber si definitivamente tiene un método, en lugar de algo a lo que puede llamar.

import inspect 

def foo(): pass 

class Test(object): 
    def method(self): pass 

print inspect.ismethod(foo) # False 
print inspect.ismethod(Test) # False 
print inspect.ismethod(Test.method) # True 
print inspect.ismethod(Test().method) # True 

print callable(foo) # True 
print callable(Test) # True 
print callable(Test.method) # True 
print callable(Test().method) # True 

callable es cierto si el argumento si el argumento es un método, una función (incluyendo lambda s), de una instancia con __call__ o una clase.

Los métodos tienen propiedades diferentes a las funciones (como im_class y). Entonces usted quiere

assert inspect.ismethod(Test().method) 
+5

+1, inspeccionar es bueno (y ese error "desafiante" realmente lee bien ;-). –

+5

http://www.d-e-f-i-n-i-t-e-l-y.com/ :-) –

+0

Usando Python 3.5, 'inspect.ismethod (Test.method)' devuelve False. – Devin

8

Si desea saber si es precisamente un método de instancia utilizar la siguiente función. (Se considera que los métodos que se definen en una metaclase y acceder a métodos de clase en clase, aunque también podrían ser considerados métodos de instancia)

import types 
def is_instance_method(obj): 
    """Checks if an object is a bound method on an instance.""" 
    if not isinstance(obj, types.MethodType): 
     return False # Not a method 
    if obj.im_self is None: 
     return False # Method is not bound 
    if issubclass(obj.im_class, type) or obj.im_class is types.ClassType: 
     return False # Method is a classmethod 
    return True 

Por lo general, la comprobación de que es una mala idea. Es más flexible utilizar cualquier método invocable() de forma intercambiable.

Cuestiones relacionadas