Логический (булев) тип — это тип данных с двумя значениями: истина (true) и ложь (false). В Python он называется bool и пишется True/False, в Java — boolean, в JavaScript — boolean, в C — bool (с C99 через <stdbool.h>, с C23 — ключевое слово). Название дано в честь математика Джорджа Буля, который в середине XIX века описал алгебру логики.
Содержание
- Три понятия, которые нужно развести
- Минимальный пример на Python
- Логические операции и таблица истинности
- Короткое замыкание (short-circuit)
andиorв Python возвращают не bool- Truthy и falsy в разных языках
- Типичная ошибка: строка «false» из конфига
- bool и числа: где тип «подменяется» целым
- Логический тип в SQL: третье значение
- Как выбрать проверку в условии
- Выводы
- Где применяется / связь с практикой
- FAQ
Ниже разберем три вещи, которые на практике путают чаще всего: логический тип как таковой, логические операции над ним и «истинность» значений других типов (truthy/falsy), по которой работают if и while. Основные примеры — на Python, для сравнения — JavaScript, Java и C. Код проверен на Python 3.9+, Node.js 22 и компиляторе C с поддержкой C99.
Три понятия, которые нужно развести
| Понятие | Что это | Пример |
|---|---|---|
| Логический тип | Тип данных ровно с двумя значениями | True, False в Python |
| Логическое выражение | Выражение, результат которого проверяют как истину или ложь | age >= 18, x in items |
| Истинность (truthiness) | Как язык трактует НЕлогическое значение в условии | if items: — пустой список ложен |
Сравнения (==, <, >=), проверка вхождения (in) и функции-предикаты вроде str.isdigit() возвращают значение логического типа. А вот if в Python и JavaScript принимает значение любого типа и сам решает, считать ли его истиной. В Java так нельзя: условие обязано быть boolean.
Минимальный пример на Python
age = 20
has_ticket = False
is_adult = age >= 18
print(is_adult, type(is_adult)) # True <class 'bool'>
can_enter = is_adult and has_ticket
print(can_enter) # False
print(not has_ticket) # True
print(is_adult != has_ticket) # True - это и есть XOR для bool
Вывод программы:
True <class 'bool'>
False
True
True
Разбор по строкам. age >= 18 — сравнение, его результат сохраняется в переменную типа bool. and дает истину, только если истинны оба операнда. not меняет значение на противоположное. Отдельного логического оператора XOR в Python нет: для двух значений типа bool его роль выполняет != (истина, когда значения разные). Побитовый ^ для bool тоже вернет bool, но для других типов это уже побитовая операция.
Логические операции и таблица истинности
| Операция | Python | Java / JavaScript / C | Истина, когда |
|---|---|---|---|
| И (конъюнкция) | and |
&& |
оба операнда истинны |
| ИЛИ (дизъюнкция) | or |
\|\| |
хотя бы один истинен |
| НЕ (отрицание) | not |
! |
операнд ложен |
| Исключающее ИЛИ | != для bool, ^ |
^ в Java, !== для bool в JS |
операнды различаются |
Таблица истинности для двух операндов:
| A | B | A и B | A или B | A xor B |
|---|---|---|---|---|
| false | false | false | false | false |
| false | true | false | true | true |
| true | false | false | true | true |
| true | true | true | true | false |
В булевой алгебре есть и другие операции, например штрих Шеффера (И-НЕ) и стрелка Пирса (ИЛИ-НЕ). В прикладном коде их отдельными операторами не пишут, они важны в схемотехнике: из одной такой операции можно собрать все остальные.
Приоритет
В Python приоритет такой: сначала сравнения, потом not, потом and, потом or. Поэтому a or b and c читается как a or (b and c). В Java порядок для логических операторов: !, затем &, ^, |, затем &&, затем ||. Практическое правило для любого языка: если в выражении смешаны И и ИЛИ, ставьте скобки — это дешевле, чем помнить таблицу приоритетов.
Короткое замыкание (short-circuit)
Короткое замыкание — вычисление второго операнда только тогда, когда без него результат неизвестен. Если левая часть and ложна, итог уже ложь, и правая часть не выполняется. Если левая часть or истинна, итог уже истина.
def check(name, value):
print("вычисляю", name)
return value
print(check("A", False) and check("B", True))
print("...")
print(check("A", True) or check("B", False))
Вывод:
вычисляю A
False
...
вычисляю A
True
Функция B не вызвалась ни разу. На этом держится частый защитный прием: сначала проверить, что объект есть, и только потом обращаться к его полям.
user = None
if user is not None and user.get("is_admin"):
print("админ")
else:
print("доступ закрыт") # доступ закрыт
Если поменять операнды местами, user.get(...) выполнится первым и упадет с AttributeError, потому что у None нет метода get.
В Java и C# есть два варианта операторов: && и || с коротким замыканием, а & и | над boolean вычисляют оба операнда всегда. Одиночные &/| полезны редко — когда у правой части есть побочный эффект, который должен выполниться при любом результате. В обычных условиях используйте && и ||.
and и or в Python возвращают не bool
Это граница упрощения «логический оператор возвращает true или false». В Python and и or возвращают один из операндов, а не обязательно True/False. То же в JavaScript для && и ||.
print(0 or "по умолчанию") # по умолчанию
print("Анна" or "по умолчанию") # Анна
print([] and 42) # []
print(not []) # True
Отсюда идиома значения по умолчанию name = value or "гость". Но у нее есть ловушка: если 0 или пустая строка — допустимые значения, они тоже заменятся на значение по умолчанию. В таком случае проверяйте явно: value if value is not None else "гость". Оператор not всегда возвращает bool.
Truthy и falsy в разных языках
Когда в условие попадает не bool, язык приводит значение к истине или лжи по своим правилам. Значения, которые считаются ложью, называют falsy, остальные — truthy.
| Язык | Что ложно в условии | Особенности |
|---|---|---|
| Python | False, None, ноль любого числового типа, пустые строка, список, кортеж, словарь, множество, range(0) |
свои классы управляют этим через __bool__ или __len__ |
| JavaScript | false, 0, -0, 0n, "", null, undefined, NaN |
пустой массив [] и объект {} истинны |
| Java | только false |
if (1) — ошибка компиляции, условие должно быть boolean |
| C | ноль (включая нулевой указатель) | любое ненулевое число — истина, результат сравнения — int 1 или 0 |
Проверка в JavaScript:
const values = [0, "", "0", [], {}, null, NaN, "false"];
for (const v of values) {
console.log(JSON.stringify(v), Boolean(v));
}
Вывод:
0 false
"" false
"0" true
[] true
{} true
null false
null false
"false" true
Строка "0" и строка "false" истинны: непустая строка всегда truthy. Вторая строка null в выводе — это NaN, его так печатает JSON.stringify.
Типичная ошибка: строка «false» из конфига
Значения из переменных окружения, форм и CSV приходят строками. Прямое приведение к bool дает неверный результат.
Неверно:
raw = "false" # например, из переменной окружения DEBUG
debug = bool(raw)
print(debug) # True
Результат: True, потому что строка непустая. Исправление — явный разбор с белым списком значений и ошибкой на неизвестном вводе:
def parse_bool(raw):
value = raw.strip().lower()
if value in ("1", "true", "yes", "on"):
return True
if value in ("0", "false", "no", "off", ""):
return False
raise ValueError("не логическое значение: " + repr(raw))
print(parse_bool("false")) # False
print(parse_bool(" TRUE ")) # True
try:
parse_bool("maybe")
except ValueError as e:
print(e) # не логическое значение: 'maybe'
Какие строки считать истиной — решение вашего проекта. Главное, чтобы неизвестное значение не превращалось молча в True или False.
bool и числа: где тип «подменяется» целым
В Python bool — подкласс int: True == 1, False == 0, и с ними работает арифметика. Это удобно для подсчета, но создает ловушки.
flags = [True, False, True, True]
print(sum(flags)) # 3 - число истинных значений
print(isinstance(True, int)) # True
print(True + True) # 2
print(1 == True, type(1) is bool) # True False
Из-за этого if x == True сработает и для x = 1. Сравнивать с True явно не нужно: пишите if x:, а если важно отличить именно True от других значений — if x is True:.
В C до стандарта C99 отдельного типа не было, истину обозначали ненулевым целым. Сейчас используют bool из <stdbool.h>:
#include <stdio.h>
#include <stdbool.h>
int main(void) {
bool ready = 5; /* любое ненулевое значение становится true */
printf("%d\n", ready); /* 1 */
printf("%d\n", 3 > 2); /* 1 - результат сравнения имеет тип int */
printf("%zu\n", sizeof(bool));
return 0;
}
Последняя строка обычно печатает 1, но размер bool в C стандартом не зафиксирован и зависит от платформы. Хотя для хранения логического значения достаточно одного бита, переменная занимает минимум адресуемую ячейку — обычно байт. Упаковка флагов в биты — отдельная техника (битовые поля, битовые маски), а не свойство типа.
Логический тип в SQL: третье значение
В SQL у логических выражений три значения: TRUE, FALSE и UNKNOWN, который возникает при сравнении с NULL. Пример в SQLite, где истина и ложь хранятся как 1 и 0:
SELECT NULL AND 0, NULL OR 1, NULL = NULL, 1 = 1;
Результат: [(0, 1, None, 1)]. NULL AND 0 — ложь, потому что ложного операнда достаточно. NULL = NULL — не истина, а NULL (UNKNOWN), поэтому для проверки пишут IS NULL. Хранение логического поля зависит от СУБД: в PostgreSQL есть тип BOOLEAN, в SQLite поле объявляют целым и ограничивают CHECK (flag IN (0, 1)).
Как выбрать проверку в условии
- Значение уже
bool(результат сравнения, флаг) — пишитеif flag:без== True. - Нужно отличить «нет значения» от нуля или пустой строки — проверяйте
is Noneявно, не полагайтесь на truthy. - Проверка «коллекция не пуста» в Python —
if items:, это идиоматично. - Значение пришло извне строкой — разбирайте явно, как
parse_boolвыше. - Второй операнд опасен без первого — ставьте защитную проверку левее, короткое замыкание не даст ему выполниться.
Выводы
- Логический тип хранит два значения, true и false; сравнения и предикаты возвращают именно его.
- Логические операции И, ИЛИ, НЕ и XOR описываются таблицей истинности; при смешении И и ИЛИ надежнее ставить скобки.
- Короткое замыкание пропускает правый операнд, если результат уже известен, — на этом строятся защитные проверки.
- Truthy/falsy различаются по языкам:
[]ложен в Python и истинен в JavaScript, а Java принимает в условии толькоboolean. - Строку «false» нельзя превращать в логическое значение через
bool()— нужен явный разбор.
Где применяется / связь с практикой
Освойте тему на практике
Логический тип встречается в каждом ветвлении, цикле, фильтре и проверке прав доступа, поэтому ошибки в нем трудно заметить: код не падает, а просто идет не по той ветке. Системно разобраться в типах, условиях и отладке таких мест на Python можно на курсе Python Developer. Basic. Посмотреть формат обучения и задать вопросы преподавателям можно на бесплатных открытых уроках.
FAQ
Почему в Python True пишется с большой буквы?
В Python 3 True и False — ключевые слова, а язык регистрозависим: true без объявления вызовет NameError.
Можно ли применять ~ к bool в Python?
Технически это побитовая инверсия целого: ~True дает -2, а не False. Начиная с Python 3.12 такое использование помечено как устаревшее, для отрицания нужен not.
Чем логический тип отличается от флага в битовой маске?
Переменная bool хранит одно значение и обычно занимает байт. Битовая маска упаковывает много флагов в одно целое, и каждый читается операцией & с нужным битом.



