2008-09-16 6 views
6

Ich habe eine Funktion in Python, die über die Attribute von dir (obj) iteriert, und ich möchte überprüfen, ob eines der enthaltenen Objekte eine Funktion, eine Methode, eine eingebaute Funktion usw. ist könnte callable() dafür verwenden, aber ich möchte keine Klassen einbeziehen. Das Beste, was ich bisher gefunden habe, ist:Gibt es eine allgemeine Möglichkeit, Python einzuchecken, wenn ein Objekt ein Funktionstyp ist?

isinstance(obj, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)) 

Gibt es eine zukunftssichere Möglichkeit, diese Überprüfung zu tun?

Edit: Ich habe vorhin falsch gesprochen, als ich sagte: "Normalerweise könnte man callable() dafür verwenden, aber ich möchte keine Klassen disqualifizieren." Ich eigentlich do möchte Klassen disqualifizieren. Ich möchte nur Funktionen entsprechen, keine Klassen.

Antwort

13

Die inspizieren Modul hat genau das, was Sie wollen:

inspect.isroutine(obj) 

FYI, der Code ist:

def isroutine(object): 
    """Return true if the object is any kind of function or method.""" 
    return (isbuiltin(object) 
      or isfunction(object) 
      or ismethod(object) 
      or ismethoddescriptor(object)) 
+2

isroutine() gibt für Teil- teilnahmen Falsch zurück. hasattr (obj, '__call__') gibt True für Partialtöne zurück. – Jim

2
if hasattr(obj, '__call__'): pass 

Das passt auch besser in Python „Duck Typing“ Philosophie, weil man nicht wirklich egal was ist es, so lange wie Sie es nennen.

Es ist erwähnenswert, dass callable() aus Python entfernt wird und in 3.0 nicht vorhanden ist.

+1

Bemerkenswert, dass dies nur für neue Stil-Klassen arbeiten. Sie erhalten False für Old-Style-Klassen. –

5

Wenn Sie möchten, Klassen und andere zufällige Objekte auszuschließen, die eine __call__ Methode, und prüfen Sie nur für Funktionen und Methoden, diese drei Funktionen in der inspect module

inspect.isfunction(obj) 
inspect.isbuiltin(obj) 
inspect.ismethod(obj) 

sollte tun, was Sie wollen in eine Zukunft haben kann sicher.

+0

Upvoted, bevorzugen Sie eine hasattr-Lösung, da Sie ein __call__-Element in einer benutzerdefinierten Klasse definieren können und hasattr wird Ihnen gerne mitteilen, dass die Klasse das Attribut __call__ hat, auch wenn es keine Funktion ist. –

+0

Ich sehe nicht, wie das ist besser als die Lösung in meinem ursprünglichen Kommentar? Sie müssen immer noch explizit nach allen drei suchen. –

1

Je nachdem, was man von 'Klasse' bedeuten:

callable(obj) and not inspect.isclass(obj) 

oder:

callable(obj) and not isinstance(obj, types.ClassType) 

Zum Beispiel Ergebnisse sind für 'dict':

>>> callable(dict) and not inspect.isclass(dict) 
False 
>>> callable(dict) and not isinstance(dict, types.ClassType) 
True 
Verwandte Themen