772 Stimmen

Was ist der Unterschied zwischen __init__ und __call__?

Ich möchte den Unterschied kennen zwischen __init__ et __call__ Methoden.

Zum Beispiel:

class test:

  def __init__(self):
    self.a = 10

  def __call__(self): 
    b = 20

20voto

Vikram Punkte 8187

__init__ würde als Konstruktor behandelt werden, während __call__ Methoden können mit Objekten beliebig oft aufgerufen werden. Beide __init__ et __call__ Funktionen nehmen Standardargumente entgegen.

18voto

Ruthvik Vaila Punkte 487

Ich werde versuchen, dies anhand eines Beispiels zu erklären: Nehmen wir an, Sie möchten eine bestimmte Anzahl von Termen aus der Fibonacci-Reihe drucken. Denken Sie daran, dass die ersten 2 Terme der Fibonacci-Reihe 1en sind. Beispiel: 1, 1, 2, 3, 5, 8, 13....

Sie möchten, dass die Liste mit den Fibonacci-Zahlen nur einmal initialisiert wird und danach aktualisiert werden soll. Jetzt können wir die __call__ Funktionalität. Lesen Sie die Antwort von @mudit verma. Sie möchten, dass das Objekt als Funktion aufrufbar ist, aber nicht jedes Mal neu initialisiert wird, wenn Sie es aufrufen.

Beispiel:

class Recorder:
    def __init__(self):
        self._weights = []
        for i in range(0, 2):
            self._weights.append(1)
        print self._weights[-1]
        print self._weights[-2]
        print "no. above is from __init__"

    def __call__(self, t):
        self._weights = [self._weights[-1], self._weights[-1] + self._weights[-2]]
        print self._weights[-1]
        print "no. above is from __call__"

weight_recorder = Recorder()
for i in range(0, 10):
    weight_recorder(i)

Die Ausgabe ist:

1
1
no. above is from __init__
2
no. above is from __call__
3
no. above is from __call__
5
no. above is from __call__
8
no. above is from __call__
13
no. above is from __call__
21
no. above is from __call__
34
no. above is from __call__
55
no. above is from __call__
89
no. above is from __call__
144
no. above is from __call__

Wenn Sie die Ausgabe beobachten __init__ wurde nur einmal aufgerufen, nämlich als die Klasse zum ersten Mal instanziiert wurde, später wurde das Objekt ohne Neuinitialisierung aufgerufen.

15voto

Dmitriy Sintsov Punkte 3403

__call__ erlaubt es, beliebige Werte zurückzugeben, während __init__ ein Konstruktor ist, gibt die Instanz der Klasse implizit zurück. Wie andere Antworten richtig bemerkten, __init__ wird nur einmal aufgerufen, während es möglich ist, die __call__ mehrfach, falls die initialisierte Instanz einer Zwischenvariablen zugewiesen wird.

>>> class Test:
...     def __init__(self):
...         return 'Hello'
... 
>>> Test()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: __init__() should return None, not 'str'
>>> class Test2:
...     def __call__(self):
...         return 'Hello'
... 
>>> Test2()()
'Hello'
>>> 
>>> Test2()()
'Hello'
>>>

10voto

Also, __init__ wird aufgerufen, wenn Sie eine Instanz einer beliebigen Klasse erstellen und auch die Instanzvariable initialisieren.

Beispiel:

class User:

    def __init__(self,first_n,last_n,age):
        self.first_n = first_n
        self.last_n = last_n
        self.age = age

user1 = User("Jhone","Wrick","40")

Y __call__ wird wie jede andere Funktion aufgerufen, wenn Sie das Objekt aufrufen.

Beispiel:

class USER:
    def __call__(self,arg):
        "todo here"
         print(f"I am in __call__ with arg : {arg} ")

user1=USER()
user1("One") #calling the object user1 and that's gonna call __call__ dunder functions

9voto

Teoman shipahi Punkte 45327

Sie können auch Folgendes verwenden __call__ Methode zu Gunsten der Implementierung Dekorateure .

Dieses Beispiel stammt aus Python 3 Muster, Rezepte und Redewendungen

class decorator_without_arguments(object):
    def __init__(self, f):
        """
        If there are no decorator arguments, the function
        to be decorated is passed to the constructor.
        """
        print("Inside __init__()")
        self.f = f

    def __call__(self, *args):
        """
        The __call__ method is not called until the
        decorated function is called.
        """
        print("Inside __call__()")
        self.f(*args)
        print("After self.f( * args)")

@decorator_without_arguments
def sayHello(a1, a2, a3, a4):
    print('sayHello arguments:', a1, a2, a3, a4)

print("After decoration")
print("Preparing to call sayHello()")
sayHello("say", "hello", "argument", "list")
print("After first sayHello() call")
sayHello("a", "different", "set of", "arguments")
print("After second sayHello() call")

出力 :

enter image description here

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X