Глядя на Queue.py в Python 2.6, я обнаружил, что эта конструкция показалась мне немного странной:
def full(self):
"""Return True if the queue is full, False otherwise
(not reliable!)."""
self.mutex.acquire()
n = 0 < self.maxsize == self._qsize()
self.mutex.release()
return n
Если maxsize
0, очередь никогда не заполнится.
Мой вопрос, как это работает в этом случае? Как 0 < 0 == 0
считается ложным?
>>> 0 < 0 == 0
False
>>> (0) < (0 == 0)
True
>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True
>>> (0) < (0 == 0)
это явно не так.n = 0 < self.maxsize == self._qsize()
прежде всего, на любом языке. Если вашим глазам приходится несколько раз метаться по линии вперед и назад, чтобы понять, что происходит, это не очень хорошо написанная строка. Просто разбейте его на несколько строк.Ответы:
Я полагаю, что в Python есть особая обработка случаев для последовательностей реляционных операторов, чтобы было легко выразить сравнения диапазонов. Гораздо приятнее говорить,
0 < x <= 5
чем говорить(0 < x) and (x <= 5)
.Это так называемые цепные сравнения . И это ссылка на документацию для них.
В других случаях, о которых вы говорите, скобки заставляют один оператор отношения применяться перед другим, поэтому они больше не являются цепочечными сравнениями. А так
True
иFalse
имеют значение как целые числа вы получите ответы , которые вы делаете из версий скобок.источник
Так как
есть
False
. Вы можете объединять операторы сравнения, и они автоматически расширяются в парные сравнения.РЕДАКТИРОВАТЬ - разъяснение о True и False в Python
В Python
True
иFalse
есть только экземплярыbool
, которые являются подклассомint
. Другими словами, наTrue
самом деле это просто 1.Дело в том, что вы можете использовать результат логического сравнения точно так же, как целое число. Это приводит к запутанным вещам, таким как
Но это произойдет, только если вы заключите сравнения в скобки, чтобы они были оценены первыми. В противном случае Python расширит операторы сравнения.
источник
'success' if result_code == 0 else 'failure'
можно переписать так('error', 'success')[result_code == 0]
, как до этого я никогда не видел логическое значение, используемое для выбора элемента в списке / кортеже.Странное поведение, которое вы испытываете, происходит от способности питонов связывать условия. Поскольку он находит 0 не меньше 0, он решает, что все выражение оценивается как ложное. Как только вы разбиваете это на отдельные условия, вы меняете функциональность. Первоначально это, по сути, тестирование
a < b && b == c
для вашего первоначального утвержденияa < b == c
.Другой пример:
источник
a < b && b == c
тоже самое, что иa < b == c
OOЭто цепное сравнение. Он возвращает истину, если каждое попарное сравнение в свою очередь истинно. Это эквивалентно
(0 < 0) and (0 == 0)
Это эквивалентно тому,
0 < True
что оценивается как True.Это эквивалентно тому,
False == 0
что оценивается как True.Эквивалент,
0 < True
которому, как указано выше, присваивается значение True.источник
Глядя на разборку (байты коды) , то понятно , почему
0 < 0 == 0
этоFalse
.Вот анализ этого выражения:
Обратите внимание на строки 0-8: эти строки проверяют,
0 < 0
что возвращаетсяFalse
в стек Python.Теперь обратите внимание на строку 11:
JUMP_IF_FALSE_OR_POP 23
это означает, что, если0 < 0
return возвращаетFalse
переход к строке 23.Теперь,
0 < 0
естьFalse
, поэтому выполняется переход, который оставляет в стеке значение,False
которое является возвращаемым значением для всего выражения0 < 0 == 0
, даже если== 0
часть даже не проверяется.Итак, в заключение, ответ, как сказано в других ответах на этот вопрос.
0 < 0 == 0
имеет особое значение. Компилятор оценивает это двумя терминами:0 < 0
и0 == 0
. Как и в случае любых сложных логических выраженийand
между ними, если первое не удается, то второе даже не проверяется.Надежды это немного просветляет, и я очень надеюсь, что метод, который я использовал для анализа этого неожиданного поведения, побудит других попробовать то же самое в будущем.
источник
Как уже упоминалось,
x comparison_operator y comparison_operator z
это синтаксический сахар(x comparison_operator y) and (y comparison_operator z)
с бонусом, который у оценивается только один раз.Таким образом, ваше выражение
0 < 0 == 0
действительно(0 < 0) and (0 == 0)
, которое оценивает,False and True
что справедливоFalse
.источник
может быть, эта выдержка из документации может помочь:
Это были сравнения, но так как вы сравниваете цепочки вы должны знать, что:
источник
Вот оно, во всей красе.
источник
Я думаю, что Python делает это странно между магией. То же, что и
1 < 2 < 3
средство 2, находится между 1 и 3.В этом случае, я думаю, что это делает [middle 0] больше, чем [left 0] и равно [right 0]. Средний 0 не больше левого 0, поэтому он оценивается как ложный.
источник