2
votes

Méthode magique Python __add__ avec des entiers

Quand j'essaye ceci:

>>> 1 .__add__(2) # notice that space after 1
3

Cela fonctionne. Mais ce

>>> 1.__add__(2)
SyntaxError: invalid syntax

ne fonctionne pas. Et cela fonctionne:

>>> "a".__add__("b")
'ab'

Que se passe-t-il ici? S'agit-il de règles de dénomination des variables et est-ce que python pense que j'essaye de créer des variables lorsque je n'utilise pas d'espace?


0 commentaires

3 Réponses :


2
votes

L'analyseur lexical python essaie d'interpréter un entier suivi d'un point comme un nombre à virgule flottante. Pour éviter cette ambiguïté, il faut ajouter un espace supplémentaire.

Pour comparaison, le même code fonctionne sans problème sur un double:

>>> (5).__add__(4)
9 

Cela fonctionne aussi si vous mettez l'int entre parenthèses:

>>> 4.23.__add__(2)
6.23


1 commentaires

Vous pouvez même utiliser deux points en cas de flottants: 1 ..__ add __ (1)



4
votes

L'analyseur Python est intentionnellement muet et simple. Lorsqu'il voit 1. , il pense que vous êtes à mi-chemin d'un nombre à virgule flottante, et 1._ n'est pas un nombre valide (ou plus correctement, 1. est un flottant valide, et vous ne pouvez pas suivre une valeur par _ : "a" __add __ ("b") est également une erreur). Ainsi, tout ce qui indique clairement que . ne fait pas partie du nombre aide: avoir un espace avant le point, comme vous l'avez découvert (puisque l'espace ne se trouve pas dans les nombres, Python abandonne l'idée d'un float et va avec la syntaxe intégrale). Les parenthèses aideraient également: (1) .__ add __ (2) . L'ajout d'un autre point fait aussi: 1 ..__ add __ (2) (ici, 1. est un nombre valide, puis .__ add__ fait le chose habituelle).


0 commentaires

2
votes

Lorsque vous utilisez 1. l'interpréteur pense que vous avez commencé à écrire un nombre flottant (vous pouvez voir dans l'EDI (au moins Pycharm) le point est bleu, pas blanc). L'espace lui indique de traiter 1. comme un nombre complet, 1.0 . 1 ..__ add __ (2) fera également l'affaire.


1 commentaires

Pour éviter ce comportement d'interpréteur, vous pouvez également utiliser le typage explicite: int (1) .__ add __ (2) ou juste des parenthèses (1) .__ add __ (2)