Je veux connaître la différence entre les méthodes __init__
et __call__
.
Par exemple:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
Le premier est utilisé pour initialiser l'objet nouvellement créé et reçoit les arguments utilisés pour ce faire:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
Le second implémente l'opérateur d'appel de fonction.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
__init__
méthode est utilisée lorsque la classe est appelée pour initialiser l'instance, tandis que la__call__
méthode est appelée lorsque l' instance est appelée__call__
?La définition d'une
__call__()
méthode personnalisée dans la méta-classe permet d'appeler l'instance de la classe en tant que fonction, sans modifier toujours l'instance elle-même.la source
__call__
permet non seulement d'utiliser une instance en tant que fonction ... mais définit le corps de la fonction qui est exécutée lorsqu'une instance est utilisée en tant que fonction.En Python, les fonctions sont des objets de première classe, cela signifie: les références de fonction peuvent être passées en entrées à d'autres fonctions et / ou méthodes, et exécutées depuis l'intérieur.
Les instances de classes (ou objets) peuvent être traitées comme s'il s'agissait de fonctions: passez-les à d'autres méthodes / fonctions et appelez-les. Pour ce faire, la
__call__
fonction de classe doit être spécialisée.def __call__(self, [args ...])
Il prend en entrée un nombre variable d'arguments. En supposantx
être une instance de la classeX
, celax.__call__(1, 2)
revient à appelerx(1,2)
ou l'instance elle-même en tant que fonction .En Python,
__init__()
est correctement défini comme constructeur de classe (tout comme__del__()
le destructeur de classe). Par conséquent, il y a une nette distinction entre__init__()
et__call__()
: le premier crée une instance de Class up, le second rend cette instance appelable comme une fonction sans impact sur le cycle de vie de l'objet lui-même (c'est__call__
-à- dire sans impact sur le cycle de vie de construction / destruction) mais il peut modifier son état interne (comme illustré ci-dessous).Exemple.
la source
def __call__
simplement pardef update
, nous donnons à la classe uneupdate
méthode qui fait la même chose. Il peut désormais également modifier l'état interne, s'il est appelé ci-dessous commes.update(7, 8)
. Alors, c'est__call__
juste du sucre syntaxique alors?__call__
rend l'instance d'une classe appelable. Pourquoi serait-il nécessaire?Techniquement, il
__init__
est appelé une fois__new__
lorsque l'objet est créé, afin qu'il puisse être initialisé.Mais il existe de nombreux scénarios où vous voudrez peut-être redéfinir votre objet, disons que vous en avez terminé avec votre objet et que vous pourriez avoir besoin d'un nouvel objet. Avec,
__call__
vous pouvez redéfinir le même objet comme s'il était nouveau.Ce n'est qu'un cas, il peut y en avoir beaucoup plus.
la source
la source
__init__
serait traité comme un constructeur où les__call__
méthodes peuvent être appelées avec des objets un certain nombre de fois. Les fonctions__init__
et__call__
acceptent les arguments par défaut.la source
__init__
n'est pas une fonction constructeur mais l'__new__
est.__init__
est appelé juste après__new__
__new__
crée l'instance de classe et recevoir une classe comme argument, alors que__init__
le constructeur d'instance qui est la raison pour laquelle il reçoitself
. Un moyen simple de voir cela est dans l'appela = Foo(1,2,3)
la fonction qui recevra les arguments du constructeur__init__
.Je vais essayer d'expliquer cela à l'aide d'un exemple, supposons que vous vouliez imprimer un nombre fixe de termes de la série fibonacci. N'oubliez pas que les 2 premiers termes de la série fibonacci sont 1s. Par exemple: 1, 1, 2, 3, 5, 8, 13 ....
Vous voulez que la liste contenant les numéros de fibonacci ne soit initialisée qu'une seule fois et ensuite elle devrait être mise à jour. Maintenant, nous pouvons utiliser la
__call__
fonctionnalité. Lisez la réponse de @mudit verma. C'est comme si vous vouliez que l'objet soit appelable en tant que fonction mais pas réinitialisé à chaque fois que vous l'appeliez.Par exemple:
La sortie est:
Si vous observez que la sortie a
__init__
été appelée une seule fois, c'est à ce moment que la classe a été instanciée pour la première fois, l'objet a ensuite été appelé sans réinitialisation.la source
Vous pouvez également utiliser la
__call__
méthode en faveur de la mise en œuvre de décorateurs .Cet exemple tiré de Python 3 Patterns, Recipes and Idioms
Sortie :
la source
Ainsi,
__init__
est appelé lorsque vous créez une instance de n'importe quelle classe et initialisez également la variable d'instance.Exemple:
Et
__call__
est appelé lorsque vous appelez l'objet comme n'importe quelle autre fonction.Exemple:
la source
__init__
est une méthode spéciale dans les classes Python, c'est la méthode constructeur d'une classe. Il est appelé chaque fois qu'un objet de la classe est construit ou on peut dire qu'il initialise un nouvel objet. Exemple:Si nous utilisons A (), cela donnera une erreur
TypeError: __init__() missing 1 required positional argument: 'a'
car il nécessite 1 argument àa
cause de__init__
.........
__call__
lorsqu'il est implémenté dans la classe nous aide à appeler l'instance de classe en tant qu'appel de fonction.Exemple:
Ici, si nous utilisons B (), il fonctionne très bien car il n'a pas de
__init__
fonction ici.la source
__call__
permet de renvoyer des valeurs arbitraires, tout en__init__
étant un constructeur retourne implicitement l'instance de classe. Comme d'autres réponses l'ont correctement souligné,__init__
est appelé une seule fois, alors qu'il est possible d'appeler__call__
plusieurs fois, au cas où l'instance initialisée est affectée à une variable intermédiaire.la source
Des réponses courtes et douces sont déjà fournies ci-dessus. Je veux fournir une implémentation pratique par rapport à Java.
Remarque : le scénario 1 et le scénario 2 semblent identiques en termes de sortie de résultats. Mais dans le scénario 1, nous créons à nouveau une autre instance1 nouvelle instance . Dans le scénario 2, nous modifions simplement l' instance1 déjà créée .
__call__
est bénéfique ici car le système n'a pas besoin de créer de nouvelle instance.Équivalent en Java
la source
Nous pouvons utiliser la méthode d' appel pour utiliser d'autres méthodes de classe comme méthodes statiques.
la source