Те, що ви бачите у всіх 3 випадках, є наслідком специфікації граматики мови та того, як лексеми, що зустрічаються у вихідному коді, аналізуються для генерування дерева розбору.
Перегляд цього коду низького рівня повинен допомогти вам зрозуміти, що відбувається під кришкою. Ми можемо взяти ці операції python, перетворити їх у байт-код і потім декомпілювати їх за допомогою dis
модуля:
Випадок 1: (0, 0) == 0, 0
>>> dis.dis(compile("(0, 0) == 0, 0", '', 'exec'))
1 0 LOAD_CONST 2 ((0, 0))
3 LOAD_CONST 0 (0)
6 COMPARE_OP 2 (==)
9 LOAD_CONST 0 (0)
12 BUILD_TUPLE 2
15 POP_TOP
16 LOAD_CONST 1 (None)
19 RETURN_VALUE
(0, 0)
спочатку порівнюється з 0
першим і оцінюється до False
. Потім з цим результатом будується кортеж і останній 0
, так що ви отримуєте (False, 0)
.
Випадок 2: 0, 0 == (0, 0)
>>> dis.dis(compile("0, 0 == (0, 0)", '', 'exec'))
1 0 LOAD_CONST 0 (0)
3 LOAD_CONST 0 (0)
6 LOAD_CONST 2 ((0, 0))
9 COMPARE_OP 2 (==)
12 BUILD_TUPLE 2
15 POP_TOP
16 LOAD_CONST 1 (None)
19 RETURN_VALUE
Кортеж побудований з, 0
як перший елемент. Для другого елемента робиться та ж перевірка, що і в першому випадку, і оцінюється False
, так що ви отримуєте (0, False)
.
Випадок 3: (0, 0) == (0, 0)
>>> dis.dis(compile("(0, 0) == (0, 0)", '', 'exec'))
1 0 LOAD_CONST 2 ((0, 0))
3 LOAD_CONST 3 ((0, 0))
6 COMPARE_OP 2 (==)
9 POP_TOP
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
Тут, як бачите, ви просто порівнюєте ці два (0, 0)
кортежі та повертаєтесь True
.