Jetzt, da klar ist, was eine Metaklasse ist , gibt es ein zugehöriges Konzept, das ich ständig verwende, ohne zu wissen, was es wirklich bedeutet.
Ich nehme an, jeder hat einmal einen Fehler mit Klammern gemacht, was zu einer Ausnahme "Objekt ist nicht aufrufbar" führte. Was mehr ist, verwenden __init__
und __new__
sich fragen, wofür dieses blutige __call__
verwendet werden kann.
Können Sie mir einige Erklärungen geben, einschließlich Beispiele mit der magischen Methode?
Antworten:
Ein Callable ist alles, was aufgerufen werden kann.
Der eingebaute in aufrufbar (PyCallable_Check in objects.c) prüft , ob das Argument entweder:
__call__
Methode oderDie genannte Methode
__call__
ist ( laut Dokumentation )Beispiel
quelle
callable
sagt Ihnen tatsächlich, ob etwas aufrufbar ist oder nicht, während Sie nach suchen,__call__
sagt Ihnen nichts; Wenn ein Objekt Trueo
bereitstellt__getattribute__
oder zurückgeben kann__getattr__
,hasattr(o, '__call__')
kanno
es dennoch nicht aufgerufen werden, da Python überspringt__getattribute__
und__getattr__
aufruft. Der einzige wirkliche Weg, um zu überprüfen, ob etwas aufrufbar ist, ist somit EAFP.callable()
in Python 3.x : " Diese Funktion wurde zuerst in Python 3.0 entfernt und dann in Python 3.2 zurückgebracht. "tp_call
überprüft wird. Siehe Implementierung von PyCallable_Check , es sind 3 Zeilen.Aus Pythons Quellen object.c :
Es sagt:
__call__
Attribut hat.x
ist aufrufbar iffx->ob_type->tp_call != NULL
Beschreibung des
tp_call
Feldes :Sie können jederzeit die integrierte
callable
Funktion verwenden, um zu bestimmen, ob ein bestimmtes Objekt aufrufbar ist oder nicht. oder besser noch anrufen undTypeError
später fangen .callable
wird in Python 3.0 und 3.1 entfernt, verwenden Siecallable = lambda o: hasattr(o, '__call__')
oderisinstance(o, collections.Callable)
.Beispiel eine vereinfachte Cache-Implementierung:
Verwendungszweck:
Beispiel aus Standardbibliothek, Datei
site.py
, Definition der integrierten Funktionenexit()
undquit()
Funktionen:quelle
def f(): ...
und Klassenobjekte wie dasclass C: ...
heißtf
,''.strip
,len
, undC
alle sind aufrufbar. Instanzen, die eine__call__()
Methode in ihrer Klasse haben, sind relativ selten.Ein aufrufbares Objekt ist ein Objekt, mit dem Sie runde Klammern () verwenden und schließlich einige Parameter übergeben können, genau wie Funktionen.
Jedes Mal, wenn Sie eine Funktion definieren, erstellt Python ein aufrufbares Objekt. Beispiel: Sie können die Funktion func folgendermaßen definieren (es ist dasselbe):
Sie könnten diese Methode anstelle von Methoden wie doit oder run verwenden . Ich denke, es ist nur klarer, obj () zu sehen als obj.doit ()
quelle
Lassen Sie mich rückwärts erklären:
Bedenken Sie...
... als syntaktischer Zucker für:
Wo
foo
kann jedes Objekt , das reagiert auf sein__call__
. Wenn ich ein Objekt sage, meine ich es: integrierte Typen, Ihre eigenen Klassen und deren Instanzen.Bei integrierten Typen beim Schreiben:
Sie tun im Wesentlichen:
Das ist auch der Grund, warum Sie es
foo = new int
in Python nicht haben : Sie lassen das Klassenobjekt einfach eine Instanz davon zurückgeben__call__
. Die Art und Weise, wie Python dies löst, ist meiner Meinung nach sehr elegant.quelle
type(int).__call__(int, '10')
undtype(unicode).__call__(unicode, '10')
. Dunders werden immer in ihrer Klasse aufgerufen, nicht über die Instanz. Und sie gehen auch nie durch die Metaklasse. In den meisten Fällen ist das nur ein Trottel, aber manchmal ist es wichtig.Ein Callable ist ein Objekt mit der
__call__
Methode. Dies bedeutet, dass Sie aufrufbare Funktionen fälschen oder nette Dinge wie Partial Function Application ausführen können, bei denen Sie eine Funktion übernehmen und etwas hinzufügen, das sie verbessert oder einige der Parameter ausfüllt, und so etwas zurückgeben, das wiederum aufgerufen werden kann ( in funktionalen Programmierkreisen als Currying bezeichnet) ).Bei bestimmten typografischen Fehlern versucht der Interpreter, etwas aufzurufen, das Sie nicht beabsichtigt haben, z. B. eine Zeichenfolge. Dies kann zu Fehlern führen, wenn der Interpreter versucht, eine nicht aufrufbare Anwendung auszuführen. Sie können dies in einem Python-Interpreter sehen, indem Sie so etwas wie das folgende Transkript ausführen.
quelle
__call__
macht jedes Objekt als Funktion aufrufbar.In diesem Beispiel wird 8 ausgegeben:
quelle
Ganz einfach, ein "aufrufbar" ist etwas, das wie eine Methode aufgerufen werden kann. Die integrierte Funktion "callable ()" zeigt an, ob etwas aufrufbar zu sein scheint, ebenso wie die Suche nach einer Call- Eigenschaft. Funktionen können ebenso wie Klassen aufgerufen werden, Klasseninstanzen können aufgerufen werden. Mehr dazu hier und hier .
quelle
In Python ist ein Callable ein Objekt, dessen Typ eine
__call__
Methode hat:So einfach ist das :)
Dies kann natürlich überladen werden:
quelle
Zu überprüfen, ob die Funktion oder Methode der Klasse aufrufbar ist oder nicht, bedeutet, dass wir diese Funktion aufrufen können.
quelle
callable(obj.__init___)
dass Sie keinen zusätzlichen Unterstrich haben (wie in AttributeError)? Wenn nicht, sind Sie sicher, dass die Antwort nichtTrue
für diese ist?Es ist etwas, nach dem Sie "(args)" setzen können und erwarten, dass es funktioniert. Ein Callable ist normalerweise eine Methode oder eine Klasse. Methoden werden aufgerufen, Klassen instanziiert.
quelle
Callables implementieren die
__call__
spezielle Methode, sodass jedes Objekt mit einer solchen Methode aufgerufen werden kann.quelle
__call__
nicht aufgerufen werden, wenn die Klasse eine solche Methode nicht definiert.Aufrufbare ist eine Art oder eine Klasse von „Build-In - Funktion oder Methode“ mit einer Methode Aufruf
Beispiel: print ist ein aufrufbares Objekt. Mit einer integrierten Funktion __call__ Wenn Sie die Druckfunktion aufrufen , erstellt Python ein Objekt vom Typ print und ruft seine Methode __call__ auf, wobei die Parameter gegebenenfalls übergeben werden.
Danke dir. Grüße, Maris
quelle
print
Funktion aufrufen , erstellt Python ein Objekt vom Typ print und ruft dessen Methode auf.__call__
" Python erstellt kein Druckobjekt. Es nennt nur etwas Äquivalentes zutype(print).__call__(print, *args, **kwargs)
. Und der erste Satz macht nicht viel Sinn. Sie scheinen ein aufrufbares Objekt zu verwirren und die Funktion "aufrufbar" zu machen.