Pourquoi utilise-t-python deux pour underscores certaines choses?
-
27-09-2019 - |
Question
Je suis assez nouveau pour les langages de programmation actuels et Python est mon premier. Je sais que mon chemin Linux un peu, assez pour obtenir un emploi d'été avec elle (je suis encore au lycée), et au travail, j'ai beaucoup de temps libre que je me sers d'apprendre Python.
Une chose a été me faire bien. Ce qui est exactement différent en Python lorsque vous avez des expressions telles que
x.__add__(y) <==> x+y
x.__getattribute__('foo') <==> x.foo
Je sais ce que les méthodes font et des choses, et je reçois ce qu'ils font, mais ma question est la suivante: comment ces méthodes sont doubles underscore ci-dessus différents de leurs équivalents plus simples à la recherche
P.S., Je ne me dérange pas d'être donné des conférences sur l'histoire de la programmation, en fait, je trouve qu'il est très utile de savoir :) Si ce sont surtout les aspects historiques de Python, vous pouvez commencer la randonnée.
La solution
Eh bien, la puissance pour le programmeur est bon, donc il devrait y avoir un moyen de personnaliser le comportement. Comme la surcharge de l'opérateur (__add__
, __div__
, __ge__
, ...), l'accès aux attributs (__getattribute__
, __getattr__
(ces deux sont differnt), __delattr__
, ...), etc. Dans de nombreux cas, comme les opérateurs, les cartes syntaxe habituelle 1: 1 le procédé respectif. Dans d'autres cas, il existe une procédure spéciale qui, à un moment donné implique d'appeler la méthode respective - par exemple, __getattr__
est appelée uniquement si l'objet n'a pas l'attribut demandé et __getattribute__
est pas mis en œuvre ou en AttributeError. Et certains d'entre eux sont des sujets vraiment avancés que vous obtenez deeeeep dans les entrailles du système d'objets et sont rarement nécessaires. Donc pas besoin de les apprendre, consultez simplement la référence lorsque vous avez besoin / voulez savoir. En parlant de référence, ici est .
Autres conseils
Voici le créateur de Python expliquant :
... plutôt que de concevoir une nouvelle syntaxe pour types particuliers de méthodes de classe (par exemple comme initializers et) Destructeurs, je ont décidé que ces fonctions pourraient être manipulé par l'utilisateur nécessitant simplement à mettre en œuvre des méthodes spéciales avec des noms tels que
__init__
,__del__
et ainsi de suite. Cette convention d'appellation était pris à partir de laquelle les identificateurs en commençant par underscores sont réservés par le compilateur et ont souvent spécial sens (par exemple, des macros telles que__FILE__
dans le préprocesseur C).
...
J'ai aussi utilisé cette technique pour permettre classes d'utilisateurs de redéfinir le comportement des opérateurs de Python. Comme précédemment noté, python est mis en oeuvre en C et utilise des tables de pointeurs de fonction mettre en œuvre diverses capacités de intégré dans les objets (par exemple, « get attribut », « ajouter » et « appel »). À permettre à ces capacités à définir dans les classes définies par l'utilisateur, je cartographié la différents pointeurs de fonction spéciale à les noms de méthodes telles que
__getattr__
,__add__
et__call__
. Il y a un correspondance directe entre ceux-ci Les noms et les tables de la fonction pointeurs on doit définir quand la mise en œuvre de nouveaux objets Python en C.
Lorsque vous démarrez une méthode avec deux underscores (et pas underscores de suivi), de Python nom mutiler règles sont appliquées. Ceci est un moyen de simuler vaguement le mot-clé private
d'autres langages OO tels que C ++ et Java. (Même si, la méthode est encore techniquement pas privé de la manière que les méthodes de Java et C sont privées, mais il est « plus difficile à obtenir à » de l'extérieur de l'instance.)
Méthodes avec deux grandes et deux underscores de fuite sont considérés comme des « intégrée » des méthodes, qui est, ils sont utilisés par l'interpréteur et sont généralement les mises en œuvre concrètes des opérateurs surchargées ou d'autres fonctionnalités intégrées.
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 +
au travail pour les classes personnalisées. Sinon, vous obtiendrez une sorte d'erreur non défini lors d'une tentative d'ajouter.
Du point de vue historique, les traits de soulignement ont souvent été utilisées comme méthode pour indiquer au programmateur que les noms doivent être considérés interne à l'emballage / / module bibliothèque qui les définit. Dans les langues qui ne fournissent pas un bon soutien pour les espaces de noms privés, en utilisant underscores est une convention d'imiter cela. En Python, lorsque vous définissez une méthode nommée '__foo__ du programmeur de maintenance connaît le nom spécial se passe quelque chose qui ne se produit pas avec une méthode nommée « foo ». Si Python avait choisi d'utiliser « ajouter » comme méthode interne de surcharge « + », alors vous ne pourriez jamais avoir une classe avec une méthode « ajouter » sans causer beaucoup de confusion. Les underscores servent de repère que la magie va se passer.
Un certain nombre d'autres questions sont maintenant marqués comme duplication de cette question, et au moins deux d'entre eux demande ce soit les méthodes de __spam__
sont appelés, ou ce que la convention est appelée, et aucune des réponses existantes couvrent que, si:
Il n'y a en fait pas de nom officiel pour les deux.
De nombreux développeurs les appellent officieusement "méthodes Dunder", pour "Double UnderScore".
Certaines personnes utilisent le terme « méthodes magiques », mais c'est quelque peu ambiguë entre ce qui signifie des méthodes Dunder, méthodes spéciales (voir ci-dessous), ou quelque chose quelque part entre les deux.
un terme officiel « attributs spéciaux », qui recouvre de près, mais pas tout à fait avec les méthodes Dunder. chapitre du modèle de données dans la référence explique jamais tout à fait ce qu'est un attribut spécial est, mais l'idée de base est qu'il est au moins un des éléments suivants:
- Un attribut qui est fourni par l'interprète lui-même ou son code builtin, comme
__name__
sur une fonction. - un attribut qui fait partie d'un protocole mis en oeuvre par l'interpréteur lui-même, comme
__add__
pour l'opérateur de+
, ou__getitem__
pour l'indexation et le tranchage. - Un attribut que l'interprète est autorisé à regarder spécialement, en ignorant l'instance et aller droit à la classe, comme
__add__
à nouveau.
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 tous (par exemple, la méthode next
sur 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, ce n'est pas rare pour stdlib ou bibliothèques externes à vouloir définir leurs propres protocoles qui fonctionnent de la même manière, comme le pickle
protocole
[Spéculation] Python a été influencée par Algol68 , Guido peut-être utilisé Algol68 au Université d'Amsterdam où Algol68 a un même « régime affiloirs » appelé « Citation planage ». En Algol68 les les opérateurs, les types et les mots clés peut apparaissent dans une police différente (en général ** gras **, ou __ souligné __), dans des fichiers SourceCode cette police de caractères est réalisée avec des guillemets, par exemple 'ABS' (citant similaire à citer en ' wikitext ')
Algol68 ⇒ python (opérateurs mis en correspondance avec des fonctions membres)
- 'et' ⇒ __and __
- 'ou' ⇒ __ __taille individuelle ou __vous
- 'non' ⇒ pas
- 'ENTIER' ⇒ __trunc __
- 'SHL' ⇒ __lshift __
- 'SHR' ⇒ __rshift __
- 'UPB' ⇒ __sizeof __
- 'long' ⇒ __long __
- 'int' ⇒ __int __
- 'réel' ⇒ __float __
- 'format' ⇒ __format __
- 'rééd' ⇒ __repr __
- 'abs' ⇒ __abs __
- 'moins' ⇒ __neg __
- 'moins' ⇒ __sub __
- 'plus' ⇒ __add __
- 'temps' ⇒ __mul __
- 'mod' ⇒ __mod __
- 'div' ⇒ __truediv __
- 'sur' ⇒ __div __
- 'up' ⇒ __pow __
- 'im' ⇒ imag
- 're' ⇒ réel
- 'conj' ⇒ conjugué
Dans ces Algol68 ont été refered comme noms en gras , par exemple abs , mais "sous-sous-abs" __abs__ en python.
Mes 2 cents: ¢ Alors parfois - comme un fantôme - lorsque vous couper et coller des classes de python dans un wiki vous comme par magie réincarner de Algol68 gras mots-clés. ¢