2009-08-11 17 views
26

Come si può verificare se una variabile è un metodo di istanza o no? Sto usando Python 2.5.Python: asserire che la variabile è un metodo di istanza?

Qualcosa di simile a questo:

class Test: 
    def method(self): 
     pass 

assert is_instance_method(Test().method) 
+16

Cosa c'è di sbagliato nel chiedere qui? – quano

+3

Leggere il sorgente non è di alcun aiuto, presumibilmente sta scrivendo del codice che deve conoscere la risposta in fase di esecuzione. Forse iterando attraverso tutti gli attr su un oggetto, per esempio. –

risposta

41

inspect.ismethod è quello che vuoi scoprire se hai sicuramente un metodo, piuttosto che solo qualcosa che puoi chiamare.

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 è vero se l'argomento se questo è un metodo, una funzione (compresi lambda s), un'istanza con __call__ o una classe.

I metodi hanno proprietà diverse dalle funzioni (come im_class e im_self). Quindi vuoi

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

+1, l'ispezione è buona (e quell'errore "provocatorio" in realtà legge bene ;-). –

+5

http://www.d-e-fi-i-i-i---y-y.com/ :-) –

+0

Utilizzando Python 3.5, 'inspect.ismethod (Test.method)' restituisce False. – Devin

8

Se vuoi sapere se è proprio un metodo di istanza utilizzare la funzione seguente. (Si ritiene che i metodi definiti in un metaclasse e accessibili su una classe metodi di classe, anche se potrebbero essere considerati metodi istanza)

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 

solito controllando che è una cattiva idea. È più flessibile poter utilizzare qualsiasi richiamabile() in modo intercambiabile con i metodi.

Problemi correlati