Используем объекты вместо True и False — truthy и falsy значения в Python
Рассказываем про ложные и истинные значения, что их делает таковыми и как, используя истинные значения, можно сократить код.
69К открытий72К показов
Значения вместо булевых переменных
В Python, как и в других языках, есть логический тип переменных bool, который имеет всего два значения: True (истина) и False (ложь). Его возвращают логические операторы (например сравнение чисел или проверка присутствия элемента в списке), и именно этот тип обычно используется в if и while. Тем не менее, явно использовать bool или операторы необязательно: существуют правила, по которым значение любого типа приводится к True или False.
Прим пер.По-английски это называется truthy и falsy, то есть «примерно-но-не-совсем-истинные», «истинноватые» значения. Общепринятого русского перевода нет, но в этой статье под истинным или ложным значением объекта всегда подразумеваются именно эти штуки, а булевы значения везде названы True и False.
Вот как это работает:
Булев контекст
Любое значение в Python при необходимости может интерпретироваться как True или False в соответствии с правилами языка. Об этом написано и в документации:
Любой объект может быть протестирован на истинность и использован в условиях if и while, а также как операнд булевых операций (and, or, not).
Если объект используется таким образом, то он находится в булевом контексте. Грубо говоря, это такое место в коде, которое требует от объекта значения либо True, либо False.
В булевом контексте может использоваться как переменная, так и выражение. Если используется выражение, значит, оценивается истинность его результата.
Объекты, которые приравниваются к False
Любой объект, для которого определен метод __len__
, возвращающий для этого объекта 0, является falsy. Документация:
По умолчанию объект считается истинным, если его класс не определяет метод __bool__, возвращающий для объекта False, или метод __len__, возвращающий для него ноль.
Последовательности и коллекции
- пустой список: [];
- пустой кортеж: ();
- пустой словарь: {};
- пустое множество: set();
- пустая строка: «»;
- пустой диапазон: range(0).
Нули любых численных типов
- целочисленный ноль: 0;
- ноль с плавающей точкой: 0.0;
- комплексный ноль: 0j.
Константы
- None;
- False.
Объекты, которые приравниваются к True
Согласно документации: По умолчанию любой объект имеет истинное значение
.
В частности, истинными являются:
- все непустые последовательности и коллекции (списки, кортежи, словари, множества, диапазоны и строки);
- все ненулевые числа;
- True.
Функция bool()
С помощью этой функции можно проверить истинность или ложность любого значения. Согласно документации, она:
Возвращает булево значение, т. е. либо True, либо False. Аргумент x конвертируется с использованием стандартной процедуры проверки истинности.
Например:
Передавать этой функции можно как значение, так и содержащую его переменную.
Зачем это нужно?
Преимущество истинных и ложных значений в том, что они позволяют сделать код кратким и понятным. Вот два примера:
Пример 1, с сообщением об ошибке:
Допустим, у нас есть функция print_even(), которая принимает в качестве аргумента список или кортеж чисел и печатает его чётные элементы. Если список пустой, то выводится сообщение:
Обратите внимание на эту строчку:
Её можно сократить до:
Если список пустой, data имеет ложное значение. Если он не пустой (то есть его длина больше нуля), то истинное. Тот же результат достигается меньшим количеством кода:
Пример 2, с исключением:
Можно использовать истинные/ложные значения, чтобы выбросить исключение, если аргумент некорректен.
Если список data пустой:
- data имеет ложное значение, эквивалентное False;
- поэтому not data эквивалентно not False, то есть True;
- поэтому условие if истинно;
- поэтому бросается исключение.
Если список не пустой:
- data имеет истинное значение, эквивалентное True;
- поэтому not data эквивалентно not True, то есть False;
- поэтому условие if ложно;
- поэтому исключение не бросается.
Истинные и ложные значения произвольных объектов
Если вы хотите, чтобы у ваших объектов были не только истинные значения, можно добавить к классу метод __bool__() и задать в нём правила, по которым будет определяться истинность или ложность объекта.
Например, у нас есть вот такой класс:
Поскольку у него нет специальных методов, все объекты этого класса имеют истинное значение:
Это можно исправить, добавив __bool__():
Теперь объект имеет истинное значение, пока на счету больше нуля. При нулевом или отрицательном балансе значение будет ложным.
Если у класса нет метода __bool__(), но есть метод __len__(), то истинность объекта определяется истинностью того, что возвращает __len__().
Вот так работает механизм, позволяющий использовать любые объекты в качестве булевых. С его помощью можно сделать код проще и понятнее; важно только не забывать осмысленно называть переменные — какое-нибудь
никуда не годится что с булевским контекстом, что без него.
Адаптированный перевод «Truthy and Falsy Values in Python: A Detailed Introduction»
Автор перевода Алексей Морозов
69К открытий72К показов