Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 97
Текст из файла (страница 97)
В частности, о том, что логические операторы в языке Python несколько отличаются от аналогичных операторов в таких языках, как C. В языке Python:•• Любое число, не равное нулю, или непустой объект интерпретируется какистина.386Глава 12. Условная инструкция if и синтаксические правила•• Числа, равные нулю, пустые объекты и специальный объект None интерпретируются как ложь.•• Операции сравнения и проверки на равенство применяются к структурамданных рекурсивно.•• Операции сравнения и проверки на равенство возвращают значение Trueили False (которые представляют собой версии чисел 1 и 0).•• Логические операторы and и or возвращают истинный или ложный объектоперанд.В двух словах, логические операторы используются для объединения результатов других проверок.
В языке Python существует три логических оператора:X and YИстина, если оба значения X и Y истинны.X or YИстина, если любое из значений X или Y истинно.not XИстина, значение X ложно (выражение возвращает значение True или False)Здесь X и Y могут быть любыми значениями истинности или выражениями,которые возвращают значения истинности (например, выражение проверкина равенство, сравнение с диапазоном значений и так далее). В языке Pythonлогические операторы имеют вид слов (вместо обозначений &&, || и !, как этореализовано в языке C).
Кроме того, логические операторы and и or возвращаютистинный или ложный объект, а не значение True или False. Рассмотрим несколько примеров, чтобы понять, как они работают:>>> 2 < 3, 3 < 2(True, False)# Меньше чем: возвращает True или False (1 или 0)Операция сравнения величин, как в данном случае, возвращает в качестве результата значение True или False, которые, как мы узнали в главах 5 и 9, в действительности являются особыми версиями целых чисел 1 и 0 (выводятся ониособым образом, а во всем остальном являются обычными числами).С другой стороны, операторы and и or всегда возвращают объект – объект либослева от оператора, либо справа.
Если действие этих операторов проверяетсяинструкцией if или другими инструкциями, они будут иметь ожидаемый результат (не забывайте, что каждый объект может интерпретироваться как истина или как ложь), но это не будут простые значения True или False.В случае оператора or интерпретатор начинает вычислять значения объектовоперандов слева направо и возвращает первый, имеющий истинное значение.Кроме того, интерпретатор прекратит дальнейшие вычисления, как только будет найден первый объект, имеющий истинное значение. Это обычно называютвычислением по короткой схеме, так как конечный результат становится известен еще до вычисления остальной части выражения:>>>(2,>>>3>>>{}2 or 3, 3 or 23)[] or 3[] or {}# Вернет левый операнд, если он имеет истинное значение# Иначе вернет правый операнд (истинный или ложный)Трехместное выражение if/else387В первой строке предыдущего примера оба операнда (2 и 3) имеют истинные (тоесть ненулевые) значения, поэтому интерпретатор всегда будет останавливатьвычисления и возвращать операнд слева.
В других двух операциях левый операнд имеет ложное значение (пустой объект), поэтому интерпретатор простовычисляет и возвращает объект справа (который может иметь как истинное,так и ложное значение).Вычисление оператора and также останавливается, как только результат станет известен, однако в этом случае интерпретатор вычисляет операнды слеванаправо и возвращает первый объект, имеющий ложное значение:>>>(3,>>>[]>>>[]2 and 3, 3 and 22)[] and {}# Вернет левый операнд, если он имеет ложное значение# Иначе вернет правый операнд (истинный или ложный)3 and []Здесь в первой строке оба операнда имеют истинные значения, поэтому интерпретатор вычислит оба операнда и вернет объект справа. Во второй проверкелевый операнд имеет ложное значение ([]), поэтому интерпретатор останавливает вычисления и возвращает его в качестве результата проверки.
В последнейпроверке левый операнд имеет истинное значение (3), поэтому интерпретаторвычисляет и возвращает объект справа (который имеет ложное значение []).Конечный результат будет тот же, что и в языке C и во многих других языках, –вы получаете значение, которое логически интерпретируется как истина илиложь при использовании в инструкции if или while. Однако в языке Pythonлогические операторы возвращают либо левый, либо правый объект, а не простое целочисленное значение.Такое поведение операторов and и or может показаться странным на первыйвзгляд, поэтому загляните во врезку «Придется держать в уме: логическиезначения», где вы найдете примеры, как иногда эта особенность может использоваться программистами на языке Python.
Кроме того, в следующем разделедемонстрируются часто встречающиеся способы использования такого поведения операторов и их замена в более свежих версиях Python.Трехместное выражение if/elseОдна из основных ролей логических операторов в языке Python заключаетсяв образовании выражений, которые выполняются так же, как условная инструкция if. Рассмотрим следующую инструкцию, которая записывает в A значение Y или Z, в зависимости от истинности значения X:if X:A = Yelse:A = ZИногда, как в данном примере, элементы инструкции настолько просты, чтокажется излишеством тратить на них четыре строки. В некоторых случаяху нас может появиться желание вложить такую конструкцию внутрь другой инструкции вместо того, чтобы выполнять присваивание переменной. Поэтим причинам (и, откровенно говоря, потому что в языке C имеется похожая388Глава 12.
Условная инструкция if и синтаксические правилавозможность)1 в версии Python 2.5 появилась новая конструкция, позволяющая записать те же действия в виде единственного выражения:A = Y if X else ZДанное выражение дает тот же результат, что и предыдущая четырехстрочная инструкция if, но выглядит она проще. Как и в предыдущей инструкции,интерпретатор выполняет выражение Y, только если объект X имеет истинноезначение, а выражение Z выполняется, только если объект X имеет ложное значение.
То есть вычисления здесь также выполняются по сокращенной схеме.Ниже приводятся несколько примеров выражения в действии:>>>>>>‘t’>>>>>>‘f’A = ‘t’ if ‘spam’ else ‘f’ # Непустая строка – это истинаAA = ‘t’ if ‘’ else ‘f’AДо версии Python 2.5 (да и после) тот же эффект можно было получить за счеткомбинирования операторов and и or благодаря тому, что они возвращают объект слева или справа:A = ((X and Y) or Z)Этот прием работает, но он скрывает в себе ловушку – он предполагает, чтоY будет иметь истинное значение. В этом случае эффект будет тот же самый:оператор and выполнится первым и вернет Y, если X имеет истинное значение.В противном случае оператор or просто вернет Z.
Другими словами, мы получаем: «if X then Y else Z».Эта комбинация операторов and/or требует некоторого времени, чтобы осознатьее при первом знакомстве, но, начиная с версии 2.5, надобность в таком приемеотпала, так как существует более наглядная конструкция Y if X else Z, которуюможно использовать в качестве выражения. Если же составляющие достаточносложны, лучше использовать полноценную инструкцию if.В качестве дополнительного примечания: в языке Python������������������������������������������следующее выражение дает похожий эффект – благодаря тому, что функция bool преобразует Xв соответствующее целое число 1 или 0, которое затем используется для выборатребуемого значения из списка:A = [Z, Y][bool(X)]Например:>>> [‘f’, ‘t’][bool(‘’)]‘f’>>> [‘f’, ‘t’][bool(‘spam’)]‘t’1В действительности, порядок следования операндов в выражении X if Y else Z в языкеPython несколько отличается от выражения Y ? X : Z в языке C.
Такой порядок былвыбран в соответствии с анализом наиболее распространенных шаблонов программирования в языке Python, а также отчасти, чтобы помочь бывшим программистам наязыке C избавиться от привычки злоупотреблять этим выражением. Не забывайте,что в языке Python исповедуется принцип – чем проще, тем лучше.Трехместное выражение if/else389Однако это далеко не то же самое, потому что в данном случае интерпретаторне использует сокращенную схему вычисления – он всегда будет вычислять обазначения Z и Y, независимо от значения X. Из-за всех этих сложностей лучшеиспользовать более простое и более понятное выражение if/else, появившеесяв версии Python 2.5. Кроме того, этим выражением не следует злоупотреблятьи следует использовать его, только если части выражения достаточно просты,в противном случае лучше использовать обычную инструкцию if, что облегчитмодификацию программного кода в будущем.
Ваши коллеги будут благодарнывам за это.Однако вы по-прежнему можете встретить конструкцию на основе комбинации and/or в программном коде, написанном до появления версии Python 2.5 (ив программном коде, написанном программистами, использовавшими язык C,и не сумевшими избавиться от прошлых привычек).Придется держать в уме: логические значенияВ языке Python часто используется прием выбора одного объекта измножества, основанный на необычном поведении логических операторов. Следующая инструкция:X = A or B or C or Noneприсвоит переменной X первый непустой (имеющий истинное значение)объект из множества объектов A, B и C или None, если все эти объекты окажутся пустыми. Этот прием стал возможен благодаря тому, что оператор or возвращает один из двух объектов и, как оказывается, это весьмараспространенная парадигма программирования на языке Python: чтобы выбрать непустой объект из фиксированного множества, достаточнопросто объединить их в выражение с помощью оператора or.