Lors de la définition d'une méthode sur une classe en Python, cela ressemble à ceci:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
Mais dans certains autres langages, tels que C #, vous avez une référence à l'objet auquel la méthode est liée avec le mot clé "this" sans le déclarer comme argument dans le prototype de la méthode.
Était-ce une décision intentionnelle de conception de langage en Python ou y a-t-il des détails d'implémentation qui nécessitent le passage de "self" comme argument?
self
pour accéder aux membres - stackoverflow.com/questions/910020/…Réponses:
J'aime citer le Zen de Python de Peters. "Explicite vaut mieux qu'implicite."
En Java et C ++, '
this.
' peut être déduit, sauf lorsque vous avez des noms de variables qui ne permettent pas de déduire. Vous en avez donc parfois besoin et parfois pas.Python choisit de rendre des choses comme cela explicites plutôt que basées sur une règle.
De plus, comme rien n'est implicite ou supposé, des parties de l'implémentation sont exposées.
self.__class__
,self.__dict__
et d'autres structures "internes" sont disponibles de manière évidente.la source
C'est pour minimiser la différence entre les méthodes et les fonctions. Il vous permet de générer facilement des méthodes dans des métaclasses ou d'ajouter des méthodes au moment de l'exécution à des classes préexistantes.
par exemple
Cela (à ma connaissance) facilite également l'implémentation du runtime python.
la source
self
dans la déclaration de fonction (attention, peut-être que cela jette des pierres d'une maison en verre, car JavaScript a unethis
sémantique de liaison assez délicate )Je suggère que l'on lise le blog de Guido van Rossum sur ce sujet - Pourquoi l'auto explicite doit rester .
la source
Python ne vous oblige pas à utiliser "self". Vous pouvez lui donner le nom que vous voulez. Vous devez juste vous rappeler que le premier argument dans un en-tête de définition de méthode est une référence à l'objet.
la source
@staticmethod
ce n'est pas le cas.Vous permet également de faire ceci: (en bref, invoquer
Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5)
retournera 12, mais le fera de la manière la plus folle.Bien sûr, c'est plus difficile à imaginer dans des langages comme Java et C #. En rendant l'auto-référence explicite, vous êtes libre de faire référence à n'importe quel objet par cette auto-référence. De plus, une telle façon de jouer avec des classes à l'exécution est plus difficile à faire dans les langages les plus statiques - ce n'est pas nécessairement une bonne ou une mauvaise chose. C'est juste que le moi explicite permet à toute cette folie d'exister.
De plus, imaginez ceci: nous aimerions personnaliser le comportement des méthodes (pour le profilage, ou de la magie noire folle). Cela peut nous amener à penser: et si nous avions une classe
Method
dont nous pouvions outrepasser ou contrôler le comportement?Et bien voilà:
Et maintenant:
InnocentClass().magic_method()
agira comme prévu. La méthode sera liée auinnocent_self
paramètre toInnocentClass
etmagic_self
à l'instance MagicMethod. Bizarre hein? C'est comme avoir 2 mots clésthis1
etthis2
dans des langages comme Java et C #. La magie comme celle-ci permet aux frameworks de faire des choses qui seraient autrement beaucoup plus verbeuses.Encore une fois, je ne veux pas commenter l'éthique de ce genre de choses. Je voulais juste montrer des choses qui seraient plus difficiles à faire sans une référence explicite.
la source
OuterClass.this
pour obtenir le «soi» de la classe externe, mais vous pouvez toujours l'utiliserthis
comme référence à elle-même; très similaire à ce que vous faites ici en Python. Pour moi, ce n'était pas plus difficile à imaginer. Cela dépend peut-être de sa maîtrise de la langue en question?Something
, qui est à son tour définie à l'intérieur d'une autre implémentation anonyme deSomething
? En python, vous pouvez bien sûr vous référer à n'importe quelle étendue.this
. Les références implicites sont impossibru en Java.this
résultat. Par exempleObject self1 = this;
(utilisez Object ou quelque chose de moins générique). Ensuite, si vous avez accès à la variable dans les champs plus, vous pouvez avoir accès àself1
,self2
...selfn
. Je pense que ceux-ci devraient être déclarés définitifs ou quelque chose, mais cela pourrait fonctionner.Je pense que la vraie raison en plus de "Le Zen de Python" est que les Fonctions sont des citoyens de première classe en Python.
Ce qui en fait essentiellement un objet. Maintenant, le problème fondamental est que si vos fonctions sont également des objets, dans le paradigme orienté objet, comment enverriez-vous des messages aux objets lorsque les messages eux-mêmes sont des objets?
Ressemble à un problème d'oeuf de poule, pour réduire ce paradoxe, la seule façon possible est de passer un contexte d'exécution aux méthodes ou de le détecter. Mais comme python peut avoir des fonctions imbriquées, il serait impossible de le faire car le contexte d'exécution changerait pour les fonctions internes.
Cela signifie que la seule solution possible est de passer explicitement «soi» (le contexte d'exécution).
Je pense donc que c'est un problème de mise en œuvre que le Zen est venu beaucoup plus tard.
la source
Je pense que cela a à voir avec le PEP 227:
la source
Comme expliqué dans self en Python, Demystified
Invocations:
init () définit trois paramètres mais nous venons d'en passer deux (6 et 8). De même distance () nécessite un mais aucun argument n'a été passé.
Pourquoi Python ne se plaint-il pas de cette différence de nombre d'arguments ?
la source
Il y a aussi une autre réponse très simple: selon le zen du python , "explicite vaut mieux qu'implicite".
la source