J'ai programmé dans un certain nombre de langages comme Java, Ruby, Haskell et Python. Je dois basculer entre plusieurs langues par jour en raison des différents projets sur lesquels je travaille. Maintenant, le problème est que j'oublie souvent d'écrire self
car le premier paramètre dans les définitions de fonction en Python est le même que pour les méthodes d'appel sur le même objet.
Cela dit, je suis assez étonné par cette approche de Python. Fondamentalement, nous devons taper plus pour faire avancer les choses, dans les langages comme Java et Ruby, les choses sont simplifiées en référençant automatiquement les variables dans l'objet actuel.
Ma question est pourquoi est-ce self
nécessaire? Est-ce purement un choix de style, ou y a-t-il une raison pour laquelle Python ne peut pas vous laisser omettre self
la façon dont Java et C ++ vous laissent omettre this
?
@staticmethod
avant la déclaration de méthode, supprime l'erreur (juste pour info et également déconseillée)Réponses:
1) Pourquoi est-il
self
requis comme paramètre explicite dans les signatures de méthode?Parce que les méthodes sont des fonctions et ne
foo.bar(baz)
sont que du sucre syntaxique pourbar(foo, baz)
. Les classes ne sont que des dictionnaires dont certaines valeurs sont des fonctions. (Les constructeurs ne sont également que des fonctions, c'est pourquoi Python n'a pas besoinnew
). Vous pouvez dire que Python rend explicite que les objets sont construits à partir de composants plus simples. Ceci est conforme à la philosophie "explicite vaut mieux qu'implicite".En revanche, en Java, les objets sont vraiment magiques et ne peuvent pas être réduits à des composants plus simples dans le langage. En Java (au moins jusqu'à Java 8), une fonction est toujours une méthode appartenant à un objet, et cette propriété ne peut pas être modifiée en raison de la nature statique du langage. Par conséquent, il n'y a aucune ambiguïté quant à ce qui
this
fait référence, il est donc logique de le définir implicitement.JavaScript est un exemple de langage qui a un implicite
this
comme Java, mais où les fonctions peuvent exister séparément des objets comme en Python. Cela conduit à beaucoup de confusion sur ce à quoi sethis
réfère lorsque les fonctions sont transmises et appelées dans différents contextes. Beaucoup pensent instinctivementthis
doivent se référer à une propriété intrinsèque de la fonction, alors qu'elle est en fait purement déterminée par la façon dont la fonction est appelée. Je crois qu'avoirthis
un paramètre explicite comme en Python rendrait cela beaucoup moins déroutant.Quelques autres avantages du
self
paramètre explicite :Les décorateurs ne sont que des fonctions qui enveloppent d'autres fonctions. Puisque les méthodes ne sont que des fonctions, les décorateurs fonctionnent tout aussi bien sur les méthodes. S'il y avait une sorte de soi implicite, les décorateurs ne travailleraient pas de manière transparente sur les méthodes.
Les méthodes de classe et les méthodes statiques ne prennent pas de paramètre d'instance. Les méthodes de classe prennent une classe comme premier argument (généralement appelé
cls
). L'expliciteself
ou lescls
paramètres rendent beaucoup plus clair ce qui se passe et ce à quoi vous avez accès dans la méthode.2) Pourquoi les variables d'instances doivent-elles toujours être qualifiées par "
self.
?En Java, vous n'avez pas besoin de préfixer les variables membres avec "
this.
", mais en Python "self.
" est toujours requis. La raison en est que Python n'a pas de syntaxe explicite pour déclarer des variables, il n'y aurait donc aucun moyen de savoir six = 7
est censé déclarer une nouvelle variable locale ou l'affecter à une variable membre. La spécificationself.
résout cette ambiguïté.la source
self.
, comme Java) est fondamentalement incompatible avec les règles de portée et lorsque vous devez y être explicite, être implicite sur le paramètre n'a plus beaucoup de sens.Il y a une raison assez simple pour laquelle AFAIK n'a pas vraiment été abordé dans le double intersite, ni ici: Python a commencé comme un langage procédural. Il était basé sur ABC, également un langage procédural.
L'Orientation-Orientation a été ajoutée plus tard, et quand elle a été ajoutée, Guido van Rossum a voulu ajouter le minimum de fonctionnalités possibles, afin de garder la conception de Python simple. Python avait déjà des
dict
s et des fonctions, alors pourquoi ajouter quelque chose de complètement nouveau au langage, quand un objet peut simplement être undict
de slots et une classe peut être simplement unedict
de fonctions? Une méthode peut être interprétée comme une fonction partiellement appliquée qui se ferme sur un seul argument distinctif. Et c'est précisément ainsi que les méthodes sont implémentées en Python: elles ne le sont pas. Ce ne sont que des fonctions qui reçoivent un argument distinctif supplémentaire.la source
Voici mes conclusions basées sur les réponses ci-dessus et en lisant la propre randonnée de Guido sur ce sujet:
La grande idée
Les fonctions sont les blocs de construction importants en Python (ou nous devrions dire le seul), en fait, nous émulons en quelque sorte la POO en utilisant des fonctions.
Étant donné qu'une classe n'est rien d'autre qu'un dictionnaire de fonctions, nous pouvons attacher n'importe quelle fonction à n'importe quelle classe au moment de l'exécution. Fondamentalement, c'est à cause de ce besoin de lancer les fonctions au moment de l'exécution que nous pouvons faire des trucs comme Monkey Patching . Voici le
self
paramètre supportant le polymorphisme paramétrique.la source