Особенности операторов and и or
В языке Python операторы and и or, как вы и ожидали, выполняют булевы операции, но они не возвращают булевы значения: результатом всегда является значение одного из операндов.
Пример 2.16. Оператор and
>>> 'a' and 'b'
'b' >>> '' and 'b'
'' >>> 'a' and 'b' and 'c'
'c'
При использовании оператора and, значения вычисляются в булевом контексте слева напрво. Значения 0, '', [], (), {} и None
являются ложью, все остальное является истиной[3]. Если у and оба операнда являются истиной, результатом будет последнее значение. В данном случае вычисляется выражение 'a', которое является истиной, затем 'b', которое также является истиной, и возвращается 'b'. | |
Если какой-либо из операндов является ложью, результатом будет первое такое значение. В данном случает '' — первое значение, являющееся ложью. | |
Все значения являются истиной, так что в результате мы получаем последнее — 'c'. |
Пример 2.17. Оператор or
>>> 'a' or 'b'
'a' >>> '' or 'b'
'b' >>> '' or [] or {}
{} >>> def sidefx(): ... print "in sidefx()" ... return 1 >>> 'a' or sidefx()
'a'
Как и для and опреранды or вычисляются в булевском контексте слева направо. Если операнд является истиной, or
немедленно возвращает результат. В данном случае 'a' — первое истинное значение. | |
or вычисляет выражение '', которое является ложью, затем 'b', которое является истиной, и возвращает 'b'. | |
Если все значения являются ложью, or возвращает последнее. or вычисляет '' (ложь), []
(ложь), затем {} (ложь) и возвращает {}. | |
Обратите внимание, что or вычисляет операнды до тех пор, пока не найдет истинное значение, остальное игнорируется. Это имеет значение, когда вычисление операнда дает сторонние эффекты. В данном случае функция sidefx не вызывается, так как для получения результата выражения с опереатором or достаточно того, что первый операнд, 'a', является истиной. |
Если вы используете C, то, наверное, знакомы с выражением bool ? a : b, которое дает a, если bool
является истиной, b, если bool
ложно. Благодаря особенностям работы операторов and и or
в Python, вы можете достигнуть анологичного эффекта.
Пример 2.18. Прием с and-or
>>> a = "first" >>> b = "second" >>> 1 and a or b
'first' >>> 0 and a or b
'second'
Синтаксис bool ? a : b в языке Python выглядит похоже. Все выражение вычисляется слева направо, так что оператор and применяется первым. 1 and 'first' дает 'first', затем 'first' or 'second' дает 'first'. | |
0 and 'first' дает 0, тогда 0 or 'second' дает 'second'. |
Пример 2.19. Когда прием с and-or не работает
>>> a = "" >>> b = "second" >>> 1 and a or b
'second'
Так как a — пустая строка, которую Python считает ложью в булевом контексте, 1 and '' дает '', а '' or 'second' дает 'second'. Ой! Это не то, что мы хотели получить. |
Прием с and-or, bool and a or b, не будет работать так же, как конструкция bool ? a : b в C, если a является ложью. |
Пример 2.20. Безопасное использование приема с and-or
>>> a = "" >>> b = "second" >>> (1 and [a] or [b])[0]
''
Так как выражение [a] является непустым списком, оно никогда не будет ложно. Даже если a равно 0, '' или другому значению, являющемуся ложью, список [a] всегда будет являться истиной, потому что содержит один элемент. |
Кажется, этот прием не стоит того, чтобы его использовать. В конце концов вы всегда можете воспользоваться интсрукцией if. Тогда зачем вся эта суета? Конечно, в большинстве случаев выбирая между двумя константами вы можете использовать простой синтаксис и не беспокоиться, потому что значение a всегда будет истинным. И даже если придется использовать более сложный синтакс, на это могут найтись весские причины: в некоторых случаях в языке Python использование инструкции if не допускается, например в lambda-функциях.
Дополнительная литература
- В обсуждаются .
Footnotes
[3] Ну, почти все. По умолчанию экземпляры классов являются истиной, но вы можете определить специальные методы в классе, чтобы его экземпляры могли быть ложью. Вы узнаете все о классах и специальных методах в главе 3.
6 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |