Запутался в приоритетах операторов в Python - PullRequest
0 голосов
/ 28 июня 2019

Я играл с логическими выражениями в интерпретаторе python, и я не могу понять, какую процедуру исполнения Python действительно использует под капотом. Я видел эту таблицу (http://www.mathcs.emory.edu/~valerie/courses/fall10/155/resources/op_precedence.html) как описание приоритета оператора, который использует python.

1)

print("this") or True and 1/0 and print("tester")

когда я набираю это в интерпретаторе python, я получаю вывод «this», а затем ошибка нулевого деления. Однако сайт, на который я ссылался, упоминает, что вызовы функций являются вторым по важности приоритетом, поэтому не следует ли сначала выполнять оба вызова функции print? Я знаю, что есть оценка короткого замыкания, но разве она не срабатывает, только когда вы достигаете уровня приоритета ands, nots и ors?

2)

True>False or print("hello")

даже это выводит только True на интерпретаторе python. почему он не выполняет вызов функции print первым?

3)

5 is 5 or 1/0

Это выводит True. Но не должно ли деление иметь более высокий приоритет, чем «есть», и не должно ли это выражение возвращать ZeroDivsionError?

Может кто-нибудь объяснить, что мне не хватает и как сказать, в каком порядке python выполнит логическое выражение?

Ответы [ 3 ]

1 голос
/ 28 июня 2019

Порядок приоритетов используется синтаксическим анализатором для построения дерева разбора. Это не означает то же самое, что и порядок оценки.

В качестве примера рассмотрим третий случай: 5 is 5 or 1/0. Порядок приоритета: /> is> or.

Дерево разбора будет выглядеть примерно так (в соответствии с приоритетом.)

     or
   /    \
  is    div
 / \    / \
5   5  1   0

Оценка (технически, генерация кода) начинается сверху, в данном случае, с узла or, согласно другому правилу, предоставленному генератору кода. Вывод генератора кода для or может выглядеть примерно так:

t = code(5 is 5)
if t goto L1
L2: code(1/0)
    goto L1
L1:

Порядок приоритета использовался только изначально для создания дерева разбора. Как только дерево разбора построено, в игру вступают семантические правила (действия? Я забыл слова).

Поведение при коротком замыкании встроено в семантическое правило узла or.

p.s. Этот ответ не предназначен специально для Python.

1 голос
/ 28 июня 2019

Может кто-нибудь объяснить, что мне не хватает и как сказать, в каком порядке python выполнит логическое выражение?

Приоритет влияет на то, каким образом «общие» операнды будут группироваться при разборе на дерево. После этого конкретная модель оценки каждого подвыражения вступает во владение.

print("this") or True and 1/0 and print("tester")

Вы получаете дерево, которое выглядит следующим образом (вы можете получить более подробную, но точную версию, используя модуль ast и astpretty, чтобы получить что-то читаемое):

    or
        print("this")
        and
             True
             and
                 1/0
                 print("tester")

Затем оценка вступает во владение (после компиляции в байт-код, но это не меняет порядок операции):

  1. оценивается внешнее or
    1. вычисляет первое print, которое возвращает ложное значение, поэтому
    2. оценивает первый and
      1. оценивает True, что правда
      2. поэтому он оценивает второй and
        1. который оценивает 1/0 который взрывается

True>False or print("hello")

Это анализирует до

or
   >
      True
      False
   print("hello")
  1. or вычисляет свой первый операнд

    1. (> True False) оценивается как True

    or является оператором короткого замыкания, он останавливается, как только находит истинное значение и возвращает его, поэтому он никогда не достигает значения print

5 is 5 or 1/0

Это разбирает на

or
    is
        5
        5
    /
        1
        0
  1. or оценивается

    1. is оценивается и возвращает True

    как указано выше, or является оператором короткого замыкания и возвращает первое истинное значение, поэтому оно сразу возвращается.

Я пропустил несколько битов, например. технически / оценивает оба операнда, затем применяет их операцию, вызовы функций оценивают все их параметры , затем выполняет сам вызов.

and и or выделяются, потому что они выполняют логику после вычисления каждого операнда, а не после оценки всех их (они ленивы / короткого замыкания): and возвращает первый ложный результат получает или возвращает первый истинный результат, который он получает, потенциально оценивая только первый из их операндов.

0 голосов
/ 28 июня 2019

Приоритет не влияет на порядок, в котором python оценивает операторы.В 5 is 5 or 1/0 python сначала проверяет, является ли 5 is 5 истиной, и если это так, он игнорирует второе утверждение.Другими словами, python всегда вычисляет первый оператор первым, независимо от приоритета

...