Этот пост изначально появился как Гостевая статья о пибитах .
Участник сообщества Pybites fusionmuck
Недавно задал интересный вопрос в слабым каналам:
Я пытаюсь вернуть голову вокруг порядка приоритета. Тестовый код перечислен без скобок. Во второй части я добавляю кронштейны для проверки моего понимания приоритета, и я получаю возвращаемое значение true. Я что-то упускаю здесь …
Сопровождается этот образец кода:
>>> lst = [2, 3, 4] >>> lst[1] * -3 < -10 == 0 False >>> (((lst[1]) * (-3)) < (-10)) == 0 True
Я люблю этот вопрос, потому что есть несколько разных концепций, но Fusionmumck все еще есть ясный вопрос – «Почему Python делает Это Когда я ожидаю, что это делать что ? “
Когда я увидела вопрос, я думал, что понял хотя бы часть того, что происходит. Мне нужно было проверить некоторые чеки, чтобы быть уверенным, и это веселые вещи, чтобы играть с. Так что давайте сделаем это вместе!
- Упрощать
- Читать или экспериментировать?
- Мстители … Разборка!
- Бонус раунд: снаружи Python
- Вынос и связанные с этим чтение
Упрощать
Я упомянул, что в исходном вопросе было несколько концепций. Может быть полезно сломать код, который мы пытаемся понять, и разделить как можно больше шума. Итак, давайте удалим некоторые элементы, такие как:
- Вытягивание предметов из списка
- Использование 0 как логическое (True/false) значение
- Отрицательные номера
И придумать пару более простых сравнений, которые все еще демонстрируют поведение из оригинального вопроса:
>>> 3 < 1 == False False >>> (3 < 1) == False True
Мы все еще не сможем объяснить, что происходит еще, но у нас гораздо более целенаправленный вопрос.
Читать или экспериментировать?
Оригинальный вопрос был о приоритете оператора в Python. Один из способов ответить на этот вопрос – проверить официальную документацию Python. Разделы на Оператор приоритет и Сравнение цепочки Определенно полезны:
Обратите внимание, что сравнения, тесты на членство и тесты идентификации имеют одинаковый приоритет и имеют элемент цепи влево на правую, как описано в разделе сравнения.
А также:
Сравнения могут быть приведены произвольно, например, x Формально, если a, b, c, …, y, z – это выражения и OP1, OP2, …, OPN – операторы сравнения, затем OP1 B OP2 C … y Opn z эквивалентно OP1 B и B OP2 C и … y opn z, за исключением того, что каждое выражение оценивается не более одного раза.) Применение того, что к нашему вопросу, это означает для сравнения, как это: Python относится к этому так: Это делает вещи намного яснее! Добавление скобок помогает превратить прикованный сравнение на отдельные явными упорядоченными операциями. Но … что, если мы хотим увидеть эту разницу в действии? Что происходит под капотом, когда мы добавляем эти скобки? Мы больше не можем сломать код, пока сохраняя поведение, которое мы пытаемся наблюдать, поэтому Питона дес Модуль может помочь нам разбить код Python во внутренние инструкции ( Bytecode ), что интерпретатор Cpython видит. Это может быть очень полезно для понимания того, как работает Python Code. Чтение Разборка вывода может быть сначала сложно, но вам не нужно понимать каждую деталь для обнаружения различий между двумя кусками кода. Итак, давайте посмотрим на некоторые байт-код для этих двух сравнений. И если это ваш первый раз, когда вы смотряте в разобранном виде Python, не паникуйте! Сосредоточьтесь на том, насколько дольше первый блок инструкции: Эти дополнительные инструкции в первом блоке работают Python, чтобы управлять Chicked сравнения Отказ Есть весело играть с Вот некоторые анимации домохозяйств, которые циклически проходят инструкции Bytecode, показывая стек оценки по пути. Если вы хотите следить со ссылкой, Этот раздел из Вот разбивка И вот Это было много слов и фотографий, чтобы сломать две операции сравнения, но я надеюсь, что вам повеселись по пути. Один хитрый аспект этого вопроса в том, что Когда вы можете использовать проще: или: Если вы приедете к Python с другого языка, правильные правила приоритета оператора Python могут уловить вас от гвардии. На языках, таких как C, C #, Java и JavaScript, реляционные сравнения, такие как Скобки требуются при цепочке операторов сравнения. Например, выражение A недействителен и может быть записан как (а). То, что я надеюсь, люди убирают от этого поста, это то, что если вы не уверены, что делает линейку кода Python, попробуйте разбирать его. Это не может повредить, и это может привести к некоторым веселым открытиям. Пост, который вдохновил я вытащить Странные целые числа Python Часть II: Константы в Bytecode Кейт Мерфи Спасибо за прочтение! Пожалуйста, оставьте какие-либо вопросы или комментарии ниже, особенно если вы знаете лучший способ создания анимации стека оценки из Python Bytecode. Сохраняйте спокойствие и код в Python! – AJ.3 < 1 == False
3 < 1 and 1 == False
Печать ()
Заявления или отладки Python имеют ограниченное использование. Но у нас все еще есть способы выглядеть ближе.Мстители … Разборка!
>>> import dis
>>> dis.dis('3 < 1 == False')
1 0 LOAD_CONST 0 (3)
2 LOAD_CONST 1 (1)
4 DUP_TOP
6 ROT_THREE
8 COMPARE_OP 0 (<)
10 JUMP_IF_FALSE_OR_POP 18
12 LOAD_CONST 2 (False)
14 COMPARE_OP 2 (==)
16 RETURN_VALUE
>> 18 ROT_TWO
20 POP_TOP
22 RETURN_VALUE
>>> dis.dis('(3 < 1) == False')
1 0 LOAD_CONST 0 (3)
2 LOAD_CONST 1 (1)
4 COMPARE_OP 0 (<)
6 LOAD_CONST 2 (False)
8 COMPARE_OP 2 (==)
10 RETURN_VALUE
дес
– Отправьте его какой-нибудь код, который вы понимаете, или некоторые, которые вы не (все же)!дес
Документация объясняет, как каждая инструкция по Bytecode взаимодействует с стеком оценки.3 <1
( Полноразмерный ):(3 < 1)
( Полноразмерный ):Бонус раунд: снаружи Python
==
и <
имеют одинаковый приоритет. Часто это не актуально, потому что вы бы вряд ли напечатаете:if a < b == False:
...
if a >= b:
...
if not a < b:
...
<
иметь более высокий приоритет, чем проверки равенства, как ==.
. Это делает 3 <1
Функционально эквивалентно (3 < 1)
. Ржавчина Отклоняет эту путаницу полностью, заставляя вас быть явным:Вынос и связанные с этим чтение
дес
Модуль чаще был:
Оригинал: “https://dev.to/ajkerrigan/under-the-hood-python-comparison-breakdown-3job”