Pourquoi python utilise-t-il deux underscores pour certaines choses?

je suis assez nouveau aux langages de programmation actuels, et Python est mon premier. Je connais un peu Linux, assez pour avoir un job d'été avec (je suis encore au lycée), et sur le tas, j'ai beaucoup de temps libre que j'utilise pour apprendre le Python.

il y a une chose qui me dérange. Qu'est-ce qui est exactement différent en Python quand vous avez des expressions comme

x.__add__(y) <==> x+y
x.__getattribute__('foo') <==> x.foo

je sais ce que font les méthodes et les trucs, et j'obtiens ce qu'ils font, mais ma question Est la suivante: en quoi ces méthodes de double underscore sont-elles différentes de leurs équivalents plus simples?

P., Je ne me dérange pas d'être sermonné sur l'histoire de la programmation, en fait, je trouve très utile de savoir :) si ce sont principalement des aspects historiques de Python, n'hésitez pas à commencer à radoter.

50
demandé sur sth 2010-08-09 22:34:45

7 réponses

Eh bien, la puissance pour le programmeur est bonne, donc il devrait y avoir un moyen de personnaliser le comportement. Comme la surcharge de l'opérateur( __add__ , __div__ , __ge__ , ...), attribut access ( __getattribute__ , __getattr__ (ces deux sont différents), __delattr__ ,...) etc. Dans de nombreux cas, comme les opérateurs, la syntaxe habituelle renvoie 1:1 à la méthode respective. Dans d'autres cas, il existe une procédure qui implique l'appel de la méthode choisie - par exemple, __getattr__ est appelé seulement si l'objet n'a pas l'attribut demandé et __getattribute__ n'est pas implémenté ou élevé AttributeError. Et certains d'entre eux sont vraiment des sujets avancés qui vous obtenez deeeeep dans les tripes du système d'objet et sont rarement nécessaires. Donc pas besoin de tous les apprendre, il suffit de consulter la référence lorsque vous avez besoin/voulez savoir. En parlant de référence, ici, c'est .

7
répondu 2010-08-09 18:48:46

voici le créateur de Python l'expliquant :

... plutôt que de concevoir une nouvelle syntaxe pour types spéciaux de méthodes de classe (telles que comme les initialiseurs et destructeurs), je ces caractéristiques pourraient être manipulé en exigeant simplement l'utilisateur pour mettre en œuvre des méthodes spéciales des noms tels que __init__ , __del__ , et ainsi de suite. Cette convention d'appellation était extrait de C où les identificateurs commencer avec des traits de soulignement sont réservés par le compilateur et ont souvent des spéciaux sens (par exemple, les macros telles que __FILE__ dans le préprocesseur C).

...

j'ai également utilisé cette technique pour permettre classes d'utilisateurs pour redéfinir le comportement des opérateurs de Python. Comme précédemment Python est implémenté en C et utilise des tables de pointeurs de fonction à mettre en œuvre diverses capacités de les objets intégrés (par exemple, "obtenir l'attribut", "ajouter" et "call"). De permettre la définition de ces capacités dans les classes définies par l'utilisateur, j'ai mappé différents pointeurs de fonction spéciales les noms de méthode tels que __getattr__ , __add__ , et __call__ . Il y a un la correspondance directe entre ces les noms et les tables de la fonction pointeurs il faut définir quand implémenter de nouveaux objets Python en C.

28
répondu Steven Rumbalski 2012-09-16 16:09:32

ils sont utilisés pour spécifier que L'interpréteur Python doit les utiliser dans des situations spécifiques.

par exemple, la fonction __add__ permet à l'opérateur + de travailler pour des classes personnalisées. Sinon, vous obtiendrez une sorte d'erreur non définie en essayant d'ajouter.

4
répondu Paul Nathan 2010-08-09 18:49:51

d'un point de vue historique, les underscores principaux ont souvent été utilisés comme méthode pour indiquer au programmeur que les noms doivent être considérés comme internes au paquet/module/bibliothèque qui les définit. Dans les langues qui ne fournissent pas un bon support pour les espaces de noms privés, l'utilisation de underscores est une convention pour imiter cela. En Python, lorsque vous définissez une méthode appelée " _ _ foo__", le programmeur de maintenance sait par le nom qu'il se passe quelque chose de spécial qui n'est pas se produit avec une méthode appelée 'foo'. Si Python avait choisi d'Utiliser 'add' comme méthode interne pour surcharger'+', alors vous ne pourriez jamais avoir une classe avec une méthode' add ' sans causer beaucoup de confusion. Les underscores servent de signal pour dire qu'une certaine magie va se produire.

3
répondu William Pursell 2010-08-09 19:06:31

un certain nombre d'autres questions sont maintenant marquées comme des doublons de cette question, et au moins deux d'entre eux demandent ce que soit les méthodes __spam__ sont appelés, ou ce que la convention est appelée, et aucune des réponses existantes ne couvrent que, donc:

il n'y a en fait aucun nom officiel pour l'un ou l'autre.

de nombreux développeurs les appellent officieusement "méthodes dunder", pour"double UNDERscore".

certaines personnes utilisent le terme "magie méthodes", mais c'est quelque peu ambigu entre la signification de méthodes dunder, méthodes spéciales (Voir ci-dessous), ou quelque chose quelque part entre les deux.


Il y est un terme officiel "attributs spéciaux", qui recouvre près, mais pas complètement avec la dsous méthodes. Le modèle de données chapitre dans la référence n'explique jamais tout à fait ce qu'est un attribut spécial, mais l'idée de base est qu'il est au moins un

  • un attribut fourni par l'interpréteur lui-même ou son code, comme __name__ sur une fonction.
  • un attribut qui fait partie d'un protocole implémenté par l'interpréteur lui-même, comme __add__ pour l'opérateur + , ou __getitem__ pour l'indexation et le tranchage.
  • Un attribut que l'interprète est autorisé à rechercher spécialement, en ignorant l'instance et je vais droit à la classe, comme __add__ encore.

la plupart des attributs spéciaux sont des méthodes, mais pas tous (par exemple, __name__ n'est pas). Et la plupart utilisent la convention "dunder", mais pas toutes (par exemple, la méthode next sur les itérateurs en Python 2.x).

et pendant ce temps, la plupart des méthodes dunder sont des attributs spéciaux, mais pas tous-en particulier, il n'est pas si rare pour les bibliothèques stdlib ou externes de vouloir définir leurs propres protocoles qui travailler de la même façon, comme le pickle protocole.

1
répondu abarnert 2015-05-11 02:21:46

[spéculation] Python a été influencé par Algol68 , Guido peut-être utilisé Algol68 à la Université D'Amsterdam où Algol68 a un similaire" "150919920" régime de stropping appelé"citation stropping". Dans Algol68 les opérateurs , types et mots clés can apparaissent dans une police de caractères différente (habituellement * * en gras **, ou __souligné __), dans les fichiers de code source ce type de caractère est réalisé avec des guillemets, par exemple 'abs' (citant similaire à citer dans wikitexte ')

Algol68 ⇒ Python (Opérateurs mappés à des fonctions membres)

  • 'et' ⇒ __et__ _ _
  • " ou " ⇒ __ou__
  • 'pas' ⇒ pas
  • "entier" ⇒ _ _ trunc _ _
  • ' shl ' ⇒ __ lshift _ _
  • ' shr '⇒ _ _ rshift _ _
  • 'remontée' ⇒ __sizeof__
  • 'long' ⇒ _ _ long _ _ _
  • ' int ' ⇒ _ _ int _ _
  • 'réel' ⇒ __float__
  • "format" ⇒ _ _ format _ _ _
  • 'repr' ⇒ _ _ repr_ _
  • ' abs ' ⇒ _ abs_ _ _
  • "moins" ⇒ _ _ nég _ _
  • 'moins' ⇒ __sous__
  • "plus" ⇒ __add _ _
  • "times" ⇒ __ mul _ _
  • ' mod '⇒ _ mod_ _
  • ' div '⇒ _ truediv _ _
  • 'plus' ⇒ __div__
  • 'jusqu'à' ⇒ __pow__
  • ' im '⇒ imag
  • 're' ⇒ réel
  • 'conj' ⇒ conjugué

dans Algol68 ces termes ont été appelés en gras les noms de , par exemple abs , mais "sous-sous-abs" __abs__ en python.

mes 2 cents: ¢ ainsi parfois - comme un fantôme-quand vous coupez et collez des classes de python dans un wiki, vous vous réincarnerez magiquement algol68 bold mots clés. * 1519210920"

0
répondu NevilleDNZ 2014-10-25 07:23:57