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
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
Fall 1:
class Example:
def __init__(self, a, b, c):
self.a=a
self.b=b
self.c=c
print("init", self.a, self.b, self.c)
Laufen:
Example(1,2,3)(7,8,9)
Ergebnis:
- init 1 2 3
- TypeError: 'Example' object is not callable
Fall 2:
class Example:
def __init__(self, a, b, c):
self.a=a
self.b=b
self.c=c
print("init", self.a, self.b, self.c)
def __call__(self, x, y, z):
self.x=x
self.y=y
self.z=z
print("call", self.x, self.y, self.z)
Laufen:
Example(1,2,3)(7,8,9)
Ergebnis:
- init 1 2 3
- call 7 8 9
Kurze und knappe Antworten sind bereits oben gegeben worden. Ich möchte eine praktische Umsetzung im Vergleich zu Java anbieten.
class test(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __call__(self, a, b, c):
self.a = a
self.b = b
self.c = c
instance1 = test(1, 2, 3)
print(instance1.a) #prints 1
#scenario 1
#creating new instance instance1
#instance1 = test(13, 3, 4)
#print(instance1.a) #prints 13
#scenario 2
#modifying the already created instance **instance1**
instance1(13,3,4)
print(instance1.a)#prints 13
Note Szenario 1 und Szenario 2 scheinen in Bezug auf das Ergebnis gleich zu sein. Aber in Szenario 1 erstellen wir wieder eine neue Instanz Instanz1 . In Szenario2, ändern wir einfach bereits erstellte Instanz1 . __call__
ist hier von Vorteil, da das System keine neue Instanz erstellen muss.
Äquivalent in Java
public class Test {
public static void main(String[] args) {
Test.TestInnerClass testInnerClass = new Test(). new TestInnerClass(1, 2, 3);
System.out.println(testInnerClass.a);
//creating new instance **testInnerClass**
testInnerClass = new Test().new TestInnerClass(13, 3, 4);
System.out.println(testInnerClass.a);
//modifying already created instance **testInnerClass**
testInnerClass.a = 5;
testInnerClass.b = 14;
testInnerClass.c = 23;
//in python, above three lines is done by testInnerClass(5, 14, 23). For this, we must define __call__ method
}
class TestInnerClass /* non-static inner class */{
private int a, b,c;
TestInnerClass(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
}
}
__init__()
kann:
None
.__call__()
kann wie eine Instanzmethode frei verwendet werden.
Zum Beispiel, Person
Klasse hat __init__()
et __call__()
wie unten dargestellt:
class Person:
def __init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name
print('"__init__()" is called.')
def __call__(self, arg):
return arg + self.f_name + " " + self.l_name
Jetzt erstellen und initialisieren wir die Instanz von Person
Klasse wie unten gezeigt:
# Here
obj = Person("John", "Smith")
Dann, __init__()
wird wie unten dargestellt aufgerufen:
"__init__()" is called.
Als nächstes rufen wir __call__()
auf 2 Arten (siehe unten):
obj = Person("John", "Smith")
print(obj("Hello, ")) # Here
print(obj.__call__("Hello, ")) # Here
Dann, __call__()
wird wie unten dargestellt aufgerufen:
"__init__()" is called.
Hello, John Smith # Here
Hello, John Smith # Here
Und, __init__()
kann wie unten gezeigt mehrmals aufgerufen werden:
obj = Person("John", "Smith")
print(obj.__init__("Tom", "Brown")) # Here
print(obj("Hello, "))
print(obj.__call__("Hello, "))
Dann, __init__()
aufgerufen wird und die Instanz von Person
Klasse reinitialisiert wird und None
wird zurückgegeben von __init__()
wie unten dargestellt:
"__init__()" is called.
"__init__()" is called. # Here
None # Here
Hello, Tom Brown
Hello, Tom Brown
Und, wenn __init__()
kehrt nicht zurück None
und wir nennen __init__()
wie unten dargestellt:
class Person:
def __init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name
print('"__init__()" is called.')
return "Hello" # Here
# ...
obj = Person("John", "Smith") # Here
Der folgende Fehler tritt auf:
TypeError: __init__() sollte None zurückgeben, nicht 'str'
Und, wenn __call__
ist nicht definiert in Person
Klasse:
class Person:
def __init__(self, f_name, l_name):
self.f_name = f_name
self.l_name = l_name
print('"__init__()" is called.')
# def __call__(self, arg):
# return arg + self.f_name + " " + self.l_name
Dann rufen wir obj("Hello, ")
wie unten dargestellt:
obj = Person("John", "Smith")
obj("Hello, ") # Here
Der folgende Fehler tritt auf:
TypeError: Objekt 'Person' ist nicht aufrufbar
Andererseits nennen wir obj.__call__("Hello, ")
wie unten dargestellt:
obj = Person("John", "Smith")
obj.__call__("Hello, ") # Here
Der folgende Fehler tritt auf:
AttributeError: Objekt 'Person' hat kein Attribut '__call__'
Wir können verwenden aufrufen Methode, um andere Klassenmethoden als statische Methoden zu verwenden.
class _Callable:
def __init__(self, anycallable):
self.__call__ = anycallable
class Model:
def get_instance(conn, table_name):
""" do something"""
get_instance = _Callable(get_instance)
provs_fac = Model.get_instance(connection, "users")
Ich möchte einige Abkürzungen und Syntaxzucker sowie einige Techniken aufzeigen, die verwendet werden können, aber ich habe sie in den aktuellen Antworten nicht gesehen.
In vielen Fällen, z.B. wenn eine APi-Anfrage gestellt werden soll und die Logik in einer Klasse gekapselt ist und wir eigentlich nur die Daten an diese Klasse übergeben und sie sofort als separate Entität ausführen wollen, wird die Klasse instantiate nicht benötigt. Das ist die
instance = MyClass() # instanciation
instance() # run the instance.__call__()
# now instance is not needed
Stattdessen können wir etwas Ähnliches tun.
class HTTPApi:
def __init__(self, val1, val2):
self.val1 = val1
self.val2 = val2
def __call__(self, *args, **kwargs):
return self.run(args, kwargs)
def run(self, *args, **kwargs):
print("hello", self.val1, self.val2, args, kwargs)
if __name__ == '__main__':
# Create a class, and call it
(HTTPApi("Value1", "Value2"))("world", 12, 213, 324, k1="one", k2="two")
Wir können eine Methode zur __call__
auch, ohne dass eine eigentliche __call__
Methode.
class MyClass:
def __init__(self, val1, val2):
self.val1 = val1
self.val2 = val2
def run(self, *args, **kwargs):
print("hello", self.val1, self.val2, args, kwargs)
__call__ = run
if __name__ == '__main__':
(MyClass("Value1", "Value"))("world", 12, 213, 324, k1="one", k2="two")
Dies ermöglicht es, eine andere globale Funktion anstelle einer Methode zu deklarieren, aus welchem Grund auch immer (es kann einige Gründe geben, zum Beispiel können Sie diese Methode nicht ändern, aber Sie brauchen sie, um von der Klasse aufgerufen zu werden).
def run(self, *args, **kwargs):
print("hello",self.val1, self.val2, args, kwargs)
class MyClass:
def __init__(self, val1, val2):
self.val1 = val1
self.val2 = val2
__call__ = run
if __name__ == '__main__':
(MyClass("Value1", "Value2"))("world", 12, 213, 324, k1="one", k2="two")
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.