Как работает bool: истинность и ложность объектов Python
Основы логического типа bool в Python
Основной подход: в Python есть два встроенных логических значения: True и False. Они относятся к типу bool. Тип bool является подклассом int, поэтому True == 1 и False == 0. В логическом контексте (в условиях if, while, тернарном выражении) Python проверяет объект на истинность и приводит его к bool.
a = True
b = False
print(type(a))
print(a == 1)
print(b == 0)
print(int(a), int(b))значение bool python (значение bool в python)
<class 'bool'> True True 1 0
длина переменной python (длина числа и переменной в python)
Функция bool() возвращает True или False для переданного объекта. Пустые коллекции, число 0, None и пустые строки считаются ложными. Непустые значения и ненулевые числа считаются истинными.
print(bool(0), bool(1))
print(bool(''), bool('text'))
print(bool([]), bool([0]))
print(bool(None))
print(bool({}), bool({'a': 1}))Python максимальное целое число (максимальное целое число в python)
False True False True False True False False True
Python list dict str str (список словарей со строковыми ключами в python)
Логические операторы and, or, not возвращают не всегда bool. and и or возвращают один из операндов, а not всегда возвращает bool. Это важно при построении выражений.
print(0 and 5)
print(3 and 5)
print(0 or 5)
print(3 or 5)
print(not 3)
print(not [])оператор float python (оператор float в python)
0 5 5 3 False True
Type 0 python (тип 0 в python)
Сравнения и проверки in, is возвращают bool. Их можно комбинировать с логическими операторами. Для явной проверки на True или False обычно достаточно самого объекта в условии, без сравнения с True.
x = 10
print(x > 5)
print(x in range(20))
print(x is None)
print(bool(x))S type python (тип s в python)
True True False True
тип элемента python (тип элемента в python)
Как получить bool из значения без функции bool()?
Использование объекта в условии автоматически вызывает проверку истинности. Это эквивалентно вызову bool(obj).
value = [1, 2]
if value:
result = 'непустой список'
else:
result = 'пустой список'
print(result)Code typing python (примеры кода с модулем typing в python)
непустой список
целое положительное число python (целое положительное число)
Такой вариант удобен для проверки коллекций, строк и чисел. Явный вызов bool() полезен, когда результат нужно сохранить или вывести.
Как преобразовать bool в другие типы?
True и False преобразуются в 1 и 0 через int(), в строки 'True' и 'False' через str().
flag = True
print(int(flag))
print(str(flag))
print(float(False))
print([flag, False])Int python значения (целочисленные значения (int) в python)
1 True 0.0 [True, False]
Set str python (множество из строки в python)
Обратное преобразование строки 'False' через bool('False') дает True, потому что строка непустая. Для разбора строк используются отдельные правила.
Как работают логические операторы and, or, not с объектами?
Оператор not приводит объект к bool и меняет значение. Операторы and и or используют короткое замыкание и возвращают последний вычисленный операнд.
a = []
b = [1]
print(a or b)
print(b and a)
print(not a)
print(a and b or 'fallback')Python словарь объектов (словарь объектов в python)
[1] [] True fallback
Str string python (функция str и строковый тип в python)
В выражении a and b or 'fallback' пустой список a ложен, поэтому and возвращает a, затем or проверяет a и возвращает 'fallback'. Такой шаблон может скрывать ошибки, если истинное значение само может быть ложным.
Как задать собственную логическую оценку для класса?
Класс может определить метод __bool__, который возвращает True или False. Если метод не определен, Python проверяет __len__.
class Box:
def __init__(self, items):
self.items = items
def __bool__(self):
return len(self.items) > 0
print(bool(Box([])))
print(bool(Box([1])))
if Box([2]):
print('коробка не пуста')
False True коробка не пуста
Метод __bool__ должен возвращать именно bool. Возврат числа или другого объекта приводит к исключению TypeError.
Как избежать сравнений с True и False?
В большинстве случаев проверка if flag: читается лучше, чем if flag == True:. Сравнение с True может давать неожиданный результат для объектов, которые равны 1.
flag = 1
print(flag == True)
print(bool(flag))
if flag:
print('истинно')
True True истинно
Если требуется строгая проверка типа и значения, применяется is True или is False. Но для обычных условий такая проверка нужна редко.
Типичные ошибки и проблемы
Проблема: bool('False') возвращает True. Строка 'False' непустая, поэтому она истинна. Для преобразования строк в bool нужна явная логика.
print(bool('False'))
print(bool('0'))
print(bool(' '))
True True True
Проблема: and и or возвращают не только bool. Код x = a or b может сохранить в x список, строку или число. Если ожидается только True или False, результат нужно обернуть в bool().
result = [] or 'default'
print(result, type(result))
print(bool(result))
default <class 'str'> True
Проблема: 1 == True и 0 == False истинны. Это следствие наследования bool от int. Для строгой проверки типа используется type(x) is bool или isinstance(x, bool).
print(1 == True)
print(type(1) is bool)
print(isinstance(True, int))
print(isinstance(1, bool))
True False True False
Проблема: __bool__ возвращает не bool, а, например, 1. Python требует именно логическое значение.
class Bad:
def __bool__(self):
return 1
try:
print(bool(Bad()))
except TypeError as e:
print(type(e).__name__, e)
TypeError __bool__ should return bool, returned int
Проблема: Проверка if x == None: работает, но идиоматичнее if x is None:. Для None сравнение is проверяет идентичность.
x = None
print(x == None)
print(x is None)
print(bool(None))
True True False
Расширенные примеры с bool в Python
Таблица истинности
for a in (False, True):
for b in (False, True):
print(a, b, a and b, a or b, not a)
False False False False True False True False True True True False False True False True True True True False
Вывод показывает результаты для всех комбинаций двух логических значений. Оператор not имеет более высокий приоритет, чем and и or.
Истинность разных объектов
values = [0, 1, -1, 0.0, 3.14, '', '0', [], [0], {}, {'a': 0}, set(), None, False, True]
for v in values:
print(repr(v), '->', bool(v))
0 -> False
1 -> True
-1 -> True
0.0 -> False
3.14 -> True
'' -> False
'0' -> True
[] -> False
[0] -> True
{} -> False
{'a': 0} -> True
set() -> False
None -> False
False -> False
True -> True
Пустые контейнеры и нулевые числа ложны. Строка '0' не пуста, поэтому она истинна. Список [0] содержит один элемент, поэтому он истинен.
Короткое замыкание с побочными эффектами
def check(name, value):
print('вызов', name)
return value
result = check('A', False) and check('B', True)
print('result =', result)
result = check('C', True) or check('D', False)
print('result =', result)
вызов A result = False вызов C result = True
В первом выражении правый операнд check('B', True) не вычисляется, потому что левый операнд ложен. Во втором выражении правый операнд check('D', False) не вычисляется, потому что левый операнд истинен.
Перегрузка __bool__ и __len__
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def __len__(self):
return len(self.items)
s = Stack()
print(bool(s))
s.push(10)
print(bool(s))
False True
Если в классе нет метода __bool__, Python использует __len__. Нулевая длина дает False, ненулевая дает True.
Сравнение и сортировка
data = [True, False, True, False]
print(sorted(data))
print(sum(data))
print(data.count(True))
print(False < True)
[False, False, True, True] 2 2 True
Так как bool является подклассом int, значения False и True участвуют в арифметике как 0 и 1. Сортировка помещает False перед True.
Побитовые операции с bool
a = True
b = False
print(a & b)
print(a | b)
print(a ^ b)
print(~a)
False True True -2
Побитовые операции с bool работают как с целыми числами. Результат может быть int, например ~True дает -2. Для логических выражений предпочтительны and, or и not.
NaN и bool
import math
nan = float('nan')
print(bool(nan))
print(nan == nan)
print(nan != nan)
True False True
float('nan') является истинным значением, но не равно самому себе. Для проверки NaN используется math.isnan().
JSON и bool
import json
data = {'active': True, 'blocked': False}
text = json.dumps(data)
print(text)
loaded = json.loads(text)
print(loaded['active'], type(loaded['active']))
{"active": true, "blocked": false}
True <class 'bool'>
В JSON логические значения записываются строчными true и false. При чтении JSON в Python они преобразуются в True и False типа bool.
Условное выражение и bool
items = []
message = 'список не пуст' if items else 'список пуст'
print(message)
flag = bool(items)
print(flag)
список пуст False
Тернарное выражение использует истинность объекта items. Пустой список дает ложное значение, поэтому выбирается ветка 'список пуст'.
Оператор := и bool
data = [0, 1, 2]
if (count := len(data)) > 2:
print('больше двух:', count)
else:
print('не больше двух:', count)
больше двух: 3
Оператор моржа := присваивает значение переменной count и возвращает его. Условие count > 2 дает True, поэтому выполняется первая ветка.
Проверка типов
print(type(True) is bool)
print(isinstance(True, bool))
print(isinstance(True, int))
print(True.__class__.__mro__)
True True True (<class 'bool'>, <class 'int'>, <class 'object'>)
Проверка показывает, что bool наследуется от int. Значение True является экземпляром и bool, и int.