2010-12-08 9 views
11

Ich schaute auf this thread, aber einige der Konzepte sind über meinem derzeitigen Niveau. In Python 2.x existiert die eingebaute Methode callable(); Gibt es eine einfache Möglichkeit zu überprüfen, ob etwas aufrufbar ist oder nicht Python 3 verwendet?Alternative zu Callable(), zur Verwendung in Python 3

+0

Ich stimme nicht mit Ihrer Wahl der akzeptierten Antwort. Ich denke [Joeforker's Antwort] (http://stackoverflow.com/a/10045780/5420829) ist besser. –

+0

Ich stimme zu. Meine Antwort ist nun veraltet - es wäre schön, wenn OP die Antwort auf eine der aktuell gültigen ändern würde. –

Antwort

9

Sie können einfach hasattr(object_name, '__call__') stattdessen tun. Anders als in Python 2.x funktioniert das für alle aufrufbare Objekte, einschließlich Klassen.

+2

In Python 2.x funktioniert es für Klassen im neuen Stil, aber nicht im alten Stil. Denken Sie daran, dass das aufgerufene "__call__" für eine (neue) Klasse "type's" (oder die Metaklasse der Klasse) ist, nicht die Klasse. – kindall

+0

@Kindall: Guter Punkt, der es wert ist, im Kopf zu behalten. Obwohl es natürlich etwas seltsam wäre, wenn es anders wäre. Dies ermöglicht es Ihnen auch, funky Dinge wie 'class_name()()' –

+0

zu tun. Bitte beachten Sie, dass dies im folgenden Eckfall ein falsch positives Ergebnis ergibt: 'Klasse C (Objekt): pass; c = C(); c .__ call__ = lambda selbst: Keine'. Obwohl 'c' jetzt eine Funktion als Attribut __call__ hat, wird 'c()' fehlschlagen, obwohl die 'hasattr'-Prüfung erfolgreich ist. Ich bin mir nicht sicher, aber ich kann nicht ausschließen, dass auch ein false-negativer corner-case möglich ist, obwohl es, wenn möglich, wahrscheinlich implementierte-in-C-Code-Objekte erfordern würde, um ihn auszulösen. – mtraceur

17

callable() ist wieder in Python 3.2.

Wenn benötigen Sie Python verwenden 3.1 (sehr unwahrscheinlich), dann zusätzlich für __call__ zu Überprüfung gibt es auch die folgenden Lösungen:

  • 2to3 ändert ein callable(x) in isinstance(x, collections.Callable)

  • sechs Anwendungen

    any("__call__" in klass.__dict__ for klass in type(x).__mro__) 
    

    Ie überprüft er für __call__ in den Basisklassen. Das erinnert mich daran, dass ich Benjamin fragen sollte warum. :)

Und schließlich kann man natürlich einfach versuchen:

try: 
    x = x() 
except TypeError: 
    pass 
+0

Große 2to3 Referenz ... das ist ein überzeugendes Argument für die Verwendung von 'collections.Callable'. ABCs sind jetzt überall, scheint es. – Russ

+6

Brilliant. Aber versuchen/außer Rat ist beängstigend. – Shekhar

+0

@Shekhar: Ausnahmebehandlung ist nicht gruselig, sobald Sie daran gewöhnt sind. –

38

Es ist zurück. Python 3.2 hat callable(); Es besteht keine Notwendigkeit mehr, eine der weniger bequemen Alternativen zu verwenden.

Verwandte Themen