2017-06-25 1 views
5
In [476]: 3 + 5 
Out[476]: 8 

In [477]: 3 +++++++++++++++++++++ 5 
Out[477]: 8 

In [478]: 3 + + + + + + + + + + + 5 
Out[478]: 8 

In [479]: 3 +++ --- +++ --- +++ 5 
Out[479]: 8 

Pourquoi il n'y a pas d'erreur SyntaxError: invalid syntax ou TypeError: bad operand type for unary +?3 +++ 5 œuvres en Python

Je sais que cela est géré dans le processus de compilation, mais comment cela fonctionne?

Répondre

5

Beause s'il y a plus d'un opérateur entre opérandes alors il fonctionnera comme ci-dessous

3 +++ 5 # it will work as 3 + (+ (+5)) 

espère qu'il efface le doute.

+2

Il convient de mentionner que '3 - 5' produit' 8', tandis que '3 --- 5' est' -2' , donc évidemment les opérateurs unaires '+' et '-' fonctionnent exactement comme prévu. –

2
+ obj 

appellera les unaire__pos__(self) (comme - obj appels __neg__(self). Répétés + et - avant obj appelleront ceux à plusieurs reprises.

++++++-+++++ 5 # = -5 

dans votre expression

3 +++++++++++++++++++++ 5 

la l'opérateur le plus à gauche puis appelez le binaire__add__ (ou __sub__). il n'y a donc aucune ambiguïté et aucune raison pour cela de soulever une erreur.

l'interpréteur python n'optimise pas ces appels (qui a sans doute à voir avec le fait que vous pouvez surcharger __pos__ et __neg__ à faire à peu près tout ce que vous voulez ...):

from dis import dis 

def f(x, y): 
    return x ++--++ y 

dis(f) 

impressions:

4   0 LOAD_FAST    0 (x) 
       3 LOAD_FAST    1 (y) 
       6 UNARY_POSITIVE 
       7 UNARY_POSITIVE 
       8 UNARY_NEGATIVE 
       9 UNARY_NEGATIVE 
      10 UNARY_POSITIVE 
      11 BINARY_ADD 
      12 RETURN_VALUE 
+0

Hey, bonne réponse! – jsalonen

+1

merci et ... de même! –

6

en utilisant le module ast nous pouvons créer la présentation abstraite arbre de syntaxe et de voir ce qui se passe:

import ast 
source = 'ADD SOURCE HERE' 
node = ast.parse(source, mode='eval') 
ast.dump(node, False, False) 

Dans le cas de 3 +++ 5, AST génère les éléments suivants expression:

'Expression(BinOp(Num(1), Add(), UnaryOp(UAdd(), UnaryOp(UAdd(), Num(2)))))' 

Ou par exemple 3 ++ -- 5 produit:

'Expression(BinOp(Num(3), Add(), UnaryOp(UAdd(), UnaryOp(USub(), Num(-5)))))' 
+0

Je me demande si 3 ------------ 5 prend plus de temps à calculer que 3 - 5. Je n'ai pas le temps de comparer maintenant ... – zmbq

+2

@zmbq oui, c'est le cas. le désassemblage montre que 'UNARY_NEGATIVE' est appelé plusieurs fois. –

+0

Je suppose que Python ne peut pas être sûr que '--x == x' – zmbq

1

L'expression est le même que:

3 + (+ (+ 5))

Toute expression numérique peut être précédée par - faire il négatif:

5-(-(3)) = 5-(-3) 
     = 5+3 
     = 8 

et

5-(-(-3)) = 5-(3) 
      = 2 

En Python, il n'y a pas d'augmentation d'échelon opérateurs comme ++ et --

en C, ce qui était probablement la source de votre confusion. Pour augmenter ou diminuer une variable i ou j en Python utilise ce style:

i += 1 
j -= 1