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
comme premier paramètre dans les définitions de fonction dans Python il en va de même avec 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
comme Java et C++ let vous omettez this
?
1) Pourquoi self
est-il requis comme paramètre explicite dans les signatures de méthode?
Parce que les méthodes sont des fonctions et foo.bar(baz)
est juste du sucre syntaxique pour bar(foo, baz)
. Les classes ne sont que des dictionnaires dont certaines valeurs sont des fonctions. (Les constructeurs ne sont aussi que des fonctions, c'est pourquoi Python n'a pas besoin de new
) Vous pouvez dire que Python rend explicite que les objets sont construits à partir de composants plus simples, conformément à 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 changée en raison de la nature statique du langage. Par conséquent, il n'y a aucune ambiguïté sur ce à quoi this
fait référence, donc elle est logique de le définir implicitement.
JavaScript est un exemple de langage qui a un this
implicite comme Java, mais où les fonctions peuvent exister séparément des objets comme en Python. Cela conduit à beaucoup de confusion sur ce à quoi this
fait référence lorsque les fonctions sont transmises et appelées dans différents contextes. Beaucoup pensent instinctivement que this
doit faire référence à 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'avoir this
comme paramètre explicite comme dans Python rendrait cela beaucoup moins déroutant.
Quelques autres avantages du paramètre explicite self
-:
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 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
). Les paramètres explicites self
ou cls
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 avec "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 si x = 7
est censé déclarer une nouvelle variable locale ou l'affecter à une variable membre. En précisant self.
résout cette ambiguïté.
Il y a une raison assez simple pour laquelle AFAIK n'a pas vraiment été abordé dans le doublon intersite, ni ici: Python a commencé comme un langage procédural. Il était basé sur ABC, également un langage procédural.
L'orientation d'objet 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à dict
s et fonctions, alors pourquoi ajouter quelque chose de complètement nouveau au langage, quand un objet peut simplement être un dict
d'emplacements et une classe peut simplement être un dict
de fonctions? Une méthode peut être interprétée comme une fonction partiellement appliquée qui se ferme sur un seul argument distingué. Et c'est précisément ainsi que les méthodes sont implémentées en Python: elles ne le sont pas. Ce sont juste des fonctions qui reçoivent une distinction supplémentaire argument.
Voici mes conclusions basées sur les réponses ci-dessus et en lisant les propres Guido divagation sur ce sujet:
La grande idée
Les fonctions sont les blocs de construction importants de Python (ou nous devrions dire le seul), en fait, nous sommes en quelque sorte en train d'émuler OOP 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 choses comme Monkey Patching . Voici le paramètre self
supportant le polymorphisme paramétrique.