Ich möchte den Unterschied zwischen __init__
und __call__
Methoden kennen.
Zum Beispiel:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
Das erste wird zum Initialisieren eines neu erstellten Objekts verwendet und empfängt dazu die folgenden Argumente:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
Der zweite implementiert einen Funktionsaufrufoperator.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
__init__
Methode wird also verwendet, wenn die Klasse aufgerufen wird, um die Instanz zu initialisieren, während die__call__
Methode aufgerufen wird, wenn die Instanz aufgerufen wird__call__
?Durch das Definieren einer benutzerdefinierten
__call__()
Methode in der Metaklasse kann die Instanz der Klasse als Funktion aufgerufen werden, wobei die Instanz selbst nicht immer geändert wird.quelle
__call__
Ermöglicht nicht nur die Verwendung einer Instanz als Funktion, sondern definiert auch den Funktionskörper, der ausgeführt wird, wenn eine Instanz als Funktion verwendet wird.In Python sind Funktionen erstklassige Objekte. Dies bedeutet: Funktionsreferenzen können in Eingaben an andere Funktionen und / oder Methoden übergeben und von dort ausgeführt werden.
Instanzen von Klassen (auch Objekte genannt) können so behandelt werden, als wären sie Funktionen: Übergeben Sie sie an andere Methoden / Funktionen und rufen Sie sie auf. Um dies zu erreichen, wird die
__call__
Klassenfunktion spezialisiert werden.def __call__(self, [args ...])
Als Eingabe wird eine variable Anzahl von Argumenten verwendet. Die Annahmex
, eine Instanz der Klasse zu seinX
, entsprichtx.__call__(1, 2)
dem Aufrufx(1,2)
oder der Instanz selbst als Funktion .Ist in Python
__init__()
ordnungsgemäß als Klassenkonstruktor definiert (ebenso wie__del__()
der Klassenzerstörer). Daher gibt es eine Nettounterscheidung zwischen__init__()
und__call__()
: Die erste erstellt eine Instanz von Class up, die zweite macht eine solche Instanz als Funktion aufrufbar , ohne den Lebenszyklus des Objekts selbst zu beeinflussen (dh__call__
hat keinen Einfluss auf den Konstruktions- / Zerstörungslebenszyklus), aber es kann seinen internen Zustand ändern (wie unten gezeigt).Beispiel.
quelle
def __call__
einfach durch ersetzendef update
, geben wir der Klasse eineupdate
Methode, die dasselbe tut. Es kann jetzt auch den internen Status ändern, wenn es unten als aufgerufen wirds.update(7, 8)
. Also, ist dann__call__
nur Syntactix Zucker?__call__
macht die Instanz einer Klasse aufrufbar. Warum sollte es erforderlich sein?Wird technisch
__init__
einmal beim__new__
Erstellen des Objekts aufgerufen , damit es initialisiert werden kann.Es gibt jedoch viele Szenarien, in denen Sie Ihr Objekt möglicherweise neu definieren möchten, beispielsweise sagen, dass Sie mit Ihrem Objekt fertig sind und möglicherweise ein neues Objekt benötigen. Mit können
__call__
Sie dasselbe Objekt neu definieren, als wäre es neu.Dies ist nur ein Fall, es kann noch viel mehr geben.
quelle
quelle
__init__
würde als Konstruktor behandelt, wobei als__call__
Methoden beliebig oft mit Objekten aufgerufen werden kann. Beide__init__
und__call__
Funktionen verwenden Standardargumente.quelle
__init__
ist keine Konstruktorfunktion,__new__
ist es aber .__init__
wird direkt nach__new__
__new__
erstellt die Klasseninstanz und empfängt eine Klasse als Argument, während dies__init__
der Instanzkonstruktor ist, weshalb er empfängtself
. Ein einfacher Weg, dies zu sehen, ist der Aufrufa = Foo(1,2,3)
der Funktion, die die Konstruktorargumente empfängt__init__
.Ich werde versuchen, dies anhand eines Beispiels zu erklären. Angenommen, Sie möchten eine feste Anzahl von Begriffen aus Fibonacci-Reihen drucken. Denken Sie daran, dass die ersten beiden Terme der Fibonacci-Reihe 1s sind. ZB: 1, 1, 2, 3, 5, 8, 13 ....
Sie möchten, dass die Liste mit den Fibonacci-Nummern nur einmal initialisiert wird und danach aktualisiert wird. Jetzt können wir die
__call__
Funktionalität nutzen. Lesen Sie die Antwort von @mudit verma. Es ist so, als ob Sie möchten, dass das Objekt als Funktion aufgerufen, aber nicht bei jedem Aufruf neu initialisiert werden kann.Z.B:
Die Ausgabe ist:
Wenn Sie feststellen, dass die Ausgabe
__init__
nur einmal aufgerufen wurde, als die Klasse zum ersten Mal instanziiert wurde, wurde das Objekt später ohne erneute Initialisierung aufgerufen.quelle
Sie können die
__call__
Methode auch zugunsten der Implementierung von Dekorateuren verwenden .Dieses Beispiel stammt aus Python 3-Mustern, Rezepten und Redewendungen
Ausgabe :
quelle
Damit,
__init__
also aufgerufen, wenn Sie eine Instanz einer Klasse erstellen und auch die Instanzvariable initialisieren.Beispiel:
Und
__call__
wird aufgerufen, wenn Sie das Objekt wie jede andere Funktion aufrufen.Beispiel:
quelle
__init__
ist eine spezielle Methode in Python-Klassen und die Konstruktormethode für eine Klasse. Es wird immer dann aufgerufen, wenn ein Objekt der Klasse erstellt wird oder wenn wir sagen können, dass es ein neues Objekt initialisiert. Beispiel:Wenn wir A () verwenden, wird ein Fehler
TypeError: __init__() missing 1 required positional argument: 'a'
ausgegeben,a
da aufgrund von 1 Argument erforderlich ist__init__
.........
__call__
Wenn es in der Klasse implementiert ist, können wir die Klasseninstanz als Funktionsaufruf aufrufen.Beispiel:
Wenn wir hier B () verwenden, läuft es einwandfrei, da es hier keine
__init__
Funktion hat.quelle
__call__
Ermöglicht die Rückgabe beliebiger Werte, während__init__
ein Konstruktor implizit die Instanz der Klasse zurückgibt. Wie andere Antworten richtig hervorgehoben haben,__init__
wird es nur einmal aufgerufen, während es möglich ist,__call__
mehrere Male aufzurufen , falls die initialisierte Instanz einer Zwischenvariablen zugewiesen ist.quelle
Kurze und süße Antworten finden Sie oben bereits. Ich möchte eine praktische Implementierung im Vergleich zu Java bereitstellen.
Hinweis : Szenario 1 und Szenario 2 scheinen in Bezug auf die Ergebnisausgabe gleich zu sein. In Szenario1 erstellen wir erneut eine neue Instanzinstanz1 . In Szenario 2 ändern wir einfach die bereits erstellte Instanz1 .
__call__
Dies ist hier von Vorteil, da das System keine neue Instanz erstellen muss.Entspricht in Java
quelle
Wir können die Aufrufmethode verwenden, um andere Klassenmethoden als statische Methoden zu verwenden.
quelle