2010-07-25 5 views
8

Документы Python говорят, что * и/имеют одинаковый приоритет.
Я знаю, что выражения в python оцениваются слева направо.Препринт оператора Python

Могу ли я рассчитывать, что и предположим, что J Дж/м всегда равна (к к)/м избежать скобки?
Если это так, я могу предположить, что это верно для операторов с одинаковым приоритетом вообще?


пс: Вопрос как это хорошо для моих целей, я пришел к нему во время чтения целочисленных только код (как в примере выше) без скобок, который в то время смотрел много подозрительных мне ,

+7

«Явный лучше, чем неявный». «Перед лицом двусмысленности отказывайтесь от соблазна угадать». - PEP 20 – msw

+0

британский: Если вы читали «целочисленный код», у вас есть гораздо большая проблема: Какую версию Python планировали использовать для ее запуска? У кода есть 'from __future__ import division' спереди? Должно ли это '/' быть прочитано как и/или изменено на '//'? –

+0

@John Machin:/означает целочисленное деление в этом случае, является python 2.6 без будущего материала, я заметил, что коды, такие как j * j/m (j * j)/m, равные, но боялись о согласованности if это поведение. –

ответ

14

Да - разные операторы с одинаковым приоритетом лево-ассоциативные; то есть будут работать два самых левых элемента, затем результат и третий элемент и т. д.

Исключение составляет ** оператор:

>>> 2 ** 2 ** 3 
256 

Кроме того, операторы сравнения (==, >, и так далее) не ведут себя в ассоциативной манере, но вместо того, чтобы перевести x [cmp] y [cmp] z в (x [cmp] y) and (y [cmp] z).

+6

Назначение на самом деле не является выражением в Python, а '=' не является оператором в обычном смысле; приоритет оператора не применяется. Назначение нескольких целей явно определено в грамматике точно так: назначение одного и того же объекта нескольким целям. –

+2

Неправильно о назначении, пример замены PLS! Единственным оператором в Python, который связан справа налево, является '**', как в '2 ** 3 ** 4' –

+0

@Amber: (1) как @ Нас Банов сказал:' ** 'является ТОЛЬКО Оператор Python, который является право-ассоциативным (2), что он является право-ассоциативным с самим собой, является незаменимым результатом факта. [1] (3) Операторы сравнения неассоциативны ... 'a

3

Короткий ответ: да.

В Python documentation says the following:

Операторы в одной коробке, имеют одинаковый приоритет. Если синтаксис явно не указан, операторы являются двоичными. Операторы в одной группе блоков слева направо (за исключением сравнений, включая тесты, все из которых имеют одинаковый приоритет и цепочку слева направо ... и экспоненциальность, которые группируются справа налево).

Итак, другими словами, ответ на ваш вопрос, да, операторы с одинаковым приоритетом будет группа слева направо, кроме Comparisions which chain rather than group:

>>> x = 0 
>>> y = 0 
>>> x == y == True 
False 
>>> (x == y) == True 
True 
>>> x == (y == True) 
True 

и возведения:

>>> 2 ** 2 ** 3 
256 
>>> (2 ** 2) ** 3 
64 
>>> 2 ** (2 ** 3) 
256 

Также , при присвоении правая часть оценивается перед левой стороной:

>>> x = 1 
>>> y = x = 2 
>>> y 
2 
+3

Назначение не является оператором (см. Выше), и цели фактически * не * оценены справа налево. Оценивается rhs присваивания, а затем оцениваются цели * слева направо * и назначаются. Вы можете увидеть различие, когда вы проверяете порядок функций, например, 'a(). A, b(). B = c(). C': вы увидите, что' c() 'вызывается, тогда Атрибут 'c' извлекается, затем вызывается' a() 'и присваивается атрибут' a', и только тогда тот же для 'b()' –

+0

. Я не имел в виду, что назначение было оператором, это почему это последнее. Я немного изменил формулировку о назначении. –

+0

Ваша формулировка по-прежнему подразумевает, что порядок оценки 'x' и' y' имеет значение для результата, присвоенного 'y'. Это не. Значения 'x' и' y' никогда не участвуют в присваивании. 'y = x = 2' строго означает« присваивать '2'' y' и 'x', а не« присваивать '2'' '', то результирующее значение 'x'' 'y' ' который, опять же, можно увидеть, когда вы включаете более сложные цели назначения, например, при использовании свойств, которые устанавливают себя в разные значения, чем вы их назначаете. –

13

Но, если это неоднозначно для вас - кодер - и это должно быть потому, что вы должны спросить, тогда ожидайте, что он будет как минимум столь же неоднозначным для читателя и потратит пару октетов для ясности.

Опираясь на правила приоритета, отлично, если вы являетесь компилятором.

добавлены ответы на комментарии:

Для человека, читающего код, который встречает неоднозначность, которая требует вне консультации для обеспечения, следует предположить, что следующий читатель будет меньше здравым смыслом, чем вы и сохранить их усилия и избегаемая человеческая ошибка разбора одной и той же конструкции и добавление к ней скобки.

Как бы то ни было, даже принятый ответ был неправильным (в обосновании, а не эффекте, см. Его первый комментарий), о котором я не знал, и ни одна из них не была частью тех, кто его поддержал.

Что касается утверждения об основной алгебре, то конкретный пример, используемый в ОП, является поучительным. Независимо от приоритета оператора выражение j * (j/m) алгебраически идентично (j * j)/m. К сожалению, алгебра Питона является лишь приближением алгебры платоновского идеала, которая может давать неверные ответы для любой формы в зависимости от величин j и m. Например:

>>> m = 1e306 
>>> m 
1e+306 
>>> j = 1e307 
>>> j 
9.9999999999999999e+306 
>>> j/m 
10.0 
>>> j*j 
inf 
>>> j * (j/m) 
1e+308 
>>> (j * j)/m 
inf 
>>> ((j * j)/m) == (j * (j/m)) 
False 

Так действительно свойство личности Python (и мой FPU) квази-алгебры не имеет. И это может отличаться на вашей машине по documentation notes в:

Числа с плавающей точкой выполняются с использованием двойной в C. Все ставки на их точности выключены, если не случится знаю машину вы работаете ,

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

+0

Я бы дал +10 на этот ответ, если бы мог. :) Это очень важный момент. – EOL

+0

Чтобы получить философский признак, принятый ответ действительно является правильным ответом на заданный вопрос. Это должно означать, что вопрос неправильный, и он находится в точке, где он спрашивает об «избегании круглых скобок». В последнее время пришлось заглянуть в рабочую, но изящно нечитаемую библиотеку, я стал очень чувствителен к различию в экспресс-стандартах Python и его использовании в обычной практике. – msw

+2

Почему вы предполагаете, что я пытаюсь написать код? что, если ... я пытаюсь читать. –

 Смежные вопросы

  • Нет связанных вопросов^_^