Die akzeptierte Antwort wurde zu dem Zeitpunkt, als sie angeboten wurde, für richtig gehalten. Wie sich stellt sich heraus, dass es eine kein Ersatz para callable()
die wieder in Python enthalten ist 3.2: Genauer gesagt, callable()
prüft die tp_call
Feld des Objekts, das getestet wird. Es gibt keine einfache Python-Entsprechung. Die meisten der vorgeschlagenen Tests sind die meiste Zeit über korrekt:
>>> class Spam(object):
... def __call__(self):
... return 'OK'
>>> can_o_spam = Spam()
>>> can_o_spam()
'OK'
>>> callable(can_o_spam)
True
>>> hasattr(can_o_spam, '__call__')
True
>>> import collections
>>> isinstance(can_o_spam, collections.Callable)
True
Wir können dem Ganzen einen Strich durch die Rechnung machen, indem wir die __call__
aus der Klasse. Und um die Sache noch spannender zu machen, fügen Sie eine gefälschte __call__
zur Instanz!
>>> del Spam.__call__
>>> can_o_spam.__call__ = lambda *args: 'OK?'
Beachten Sie, dass dies wirklich nicht aufrufbar ist:
>>> can_o_spam()
Traceback (most recent call last):
...
TypeError: 'Spam' object is not callable
callable()
liefert das richtige Ergebnis:
>>> callable(can_o_spam)
False
Aber hasattr
es falsch :
>>> hasattr(can_o_spam, '__call__')
True
can_o_spam
hat dieses Attribut doch; es wird nur nicht verwendet, wenn die der Instanz.
Noch subtiler, isinstance()
ist auch hier falsch:
>>> isinstance(can_o_spam, collections.Callable)
True
Denn wir haben diese Prüfung früher verwendet und die Methode später gelöscht, abc.ABCMeta
zwischenspeichert das Ergebnis. Dies ist wohl ein Fehler in abc.ABCMeta
. Das heißt, gibt es wirklich keine Möglichkeit, dass es könnte ein genaueres Ergebnis liefern als das Ergebnis als bei der Verwendung von callable()
selbst, da die typeobject->tp_call
Die Slot-Methode ist auf keine andere Weise zugänglich.
Verwenden Sie einfach callable()
61 Stimmen
Ich bin deprimiert über die Anzahl der Antworten, die das Problem umgehen, indem sie nach einigen aufrufen Attribut oder aufrufbare Funktion... Ein sauberer Weg ist über type(a) == types.functionType wie von @ryan vorgeschlagen
65 Stimmen
@AsTeR Die richtige Art und Weise, die Eigenschaften von Objekten mit dem Typ "Ente" zu prüfen, besteht darin, sie zu fragen, ob sie quaken, und nicht zu sehen, ob sie in einen Behälter in Entengröße passen. Der Ansatz "direkt vergleichen" wird für viele Funktionen, wie z.B. Builtins, die falsche Antwort geben.
5 Stimmen
@JohnFeminella Ich stimme Ihnen zwar im Prinzip zu. Der OP hat nicht gefragt, ob es aufrufbar ist, sondern nur, ob es eine Funktion ist. Vielleicht könnte man argumentieren, dass er eine Unterscheidung zwischen z.B. Funktionen und Klassen benötigt?
11 Stimmen
@AsTeR Es ist types.FunctionType, mit einem großen F.
0 Stimmen
@BenMares Ich kann nicht mehr editieren, aber danke, dass du es bemerkt hast!
0 Stimmen
@AsTeR Yeep saubere Art und Weise, aber das hängt irgendwie von der Person ab, die im Internet liest, ihre Entscheidung :) froh, dass Ryan es angesprochen hat.
3 Stimmen
使用方法
inspect.isfunction(object)
das im Modul inspect vorhanden ist.