2017-06-25 15 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 

Dlaczego nie ma błędu SyntaxError: invalid syntax lub TypeError: bad operand type for unary +?Dlaczego 3 +++ 5 działa w Pythonie

Wiem, że to zostało obsłużone w procesie kompilacji, ale jak to działa?

Odpowiedz

5

beause jeśli istnieje więcej niż jeden operator pomiędzy argumentu to będzie działać jak poniżej

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

Nadzieję, że czyści swoje wątpliwości.

+2

Warto wspomnieć, że '3 - 5' produkuje' 8', a '3 --- 5' jest' -2' , więc oczywiście jednoargumentowe operatory '+' i '-' działają dokładnie zgodnie z oczekiwaniami. –

2
+ obj 

wezwie jednoskładnikowa__pos__(self) (podobnie jak - obj połączeń __neg__(self). Powtórzony + i - przed obj wezwie te wielokrotnie.

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

w swojej wypowiedzi

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

się najbardziej lewy operator następnie wywołaj kod binarny__add__ (lub __sub__). więc nie ma dwuznaczności i nie ma powodu, aby to spowodować błąd.

Interpreter python nie optymalizuje tych połączeń (co prawdopodobnie ma związek z tym, że można przeciążać __pos__ i __neg__, aby zrobić prawie wszystko, co chcesz ...):

from dis import dis 

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

dis(f) 

drukuje:

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

Hej, świetna odpowiedź! – jsalonen

+1

dzięki i ... podobnie! –

6

Korzystanie moduł ast możemy stworzyć streszczenie prezentacji drzewo składni i zobaczyć, co się dzieje:

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

W przypadku 3 +++ 5 AST generuje następujący wyrażenie:

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

lub, na przykład 3 ++ -- 5 sporządza:

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

Zastanawiam się, czy 3 ------------ 5 trwa dłużej, aby obliczyć niż 3 - 5. Nie mam czasu na benchmark teraz ... – zmbq

+2

@zmbq tak, to robi. Demontaż pokazuje, że 'UNARY_NEGATIVE' jest wywoływany kilka razy. –

+0

Chyba Python nie może być pewny, że '--x == x' – zmbq

1

wyrażenia jest jak poniżej:

3 + (+ (5))

Każde wyrażenie liczbowa może być poprzedzone - do to negatywne:

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

i

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

W Pythonie nie istnieją operatory inkrementacji jak ++ i --

w C, który był prawdopodobnie źródłem swojej pomyłki. Aby zwiększyć lub zmniejszyć zmienną I lub J w Pythonie użyć tego stylu:

i += 1 
j -= 1 
Powiązane problemy