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

Tại sao không có lỗi SyntaxError: invalid syntax hoặc TypeError: bad operand type for unary +?Tại sao 3 +++ 5 hoạt động trong Python

Tôi biết điều này được xử lý trong quá trình biên dịch, nhưng cách hoạt động?

Trả lời

5

beause nếu có nhiều hơn một nhà điều hành giữa toán hạng sau đó nó sẽ làm việc như sau

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

Hy vọng nó xóa nghi ngờ của bạn.

+2

Điều đáng nói là '3 - 5' tạo' 8', trong khi '3 --- 5' là' -2' , do đó, rõ ràng các toán tử đơn nhất '+' và '-' hoạt động chính xác như mong đợi. –

2
+ obj 

sẽ gọi unary__pos__(self) (cũng giống như - obj cuộc gọi __neg__(self). Lặp đi lặp lại +- trước obj sẽ gọi những nhiều lần.

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

trong biểu hiện của bạn

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

sự toán tử bên trái sau đó gọi số nhị phân__add__ (hoặc __sub__). do đó, không có sự mơ hồ và không có lý do để điều này gây ra lỗi.

trình thông dịch trăn không tối ưu hóa các cuộc gọi này (có thể phải làm với thực tế là bạn có thể quá tải __pos____neg__ để thực hiện khá nhiều thứ bạn muốn ...):

from dis import dis 

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

dis(f) 

in:

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, câu trả lời tuyệt vời! – jsalonen

+1

cảm ơn và ... tương tự! –

6

Sử dụng ast mô-đun chúng ta có thể tạo ra trừu tượng trình bày cây cú pháp và xem những gì sẽ xảy ra:

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

Trong trường hợp của 3 +++ 5, AST tạo ra sau biểu thức:

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

Hoặc ví dụ 3 ++ -- 5 sản xuất:

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

Tôi tự hỏi nếu 3 ------------ 5 mất nhiều thời gian để tính toán hơn 3 - 5. Tôi không có thời gian để chuẩn bây giờ ... – zmbq

+2

@zmbq vâng, nó có. việc tháo gỡ cho thấy rằng 'UNARY_NEGATIVE' được gọi nhiều lần. –

+0

Tôi đoán Python không thể chắc chắn rằng '--x == x' – zmbq

1

Khái niệm cũng giống như:

3 + (+ (+ 5))

bất cứ biểu thức số có thể được đi trước bởi - để làm cho nó tiêu cực:

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

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

Trong Python, không có nhà khai thác tăng như ++--

trong C, mà có lẽ là nguồn gốc của sự nhầm lẫn của mình. Để tăng hoặc giảm biến i hoặc j bằng Python sử dụng kiểu này:

i += 1 
j -= 1 
Các vấn đề liên quan