Skip to content

Latest commit

 

History

History
76 lines (54 loc) · 3.98 KB

File metadata and controls

76 lines (54 loc) · 3.98 KB

bool

← str · 🏠 Домой · Область видимости →


Что такое bool и почему это не отдельный тип?

Коротко. bool — подкласс int. True — это единица, False — ноль, и они ведут себя как числа везде, где числа уместны.

issubclass(bool, int)     # True
isinstance(True, int)     # True
bool.__mro__              # (<class 'bool'>, <class 'int'>, <class 'object'>)

True == 1                 # True
True + True               # 2
sum([True, True, False])  # 2

Это самый частый вопрос про bool на собеседовании, и у него есть практическое следствие: подсчитать количество подходящих элементов можно просто суммой условий — sum(x > 0 for x in data).

Подвох. Раз True == 1 и хеши совпадают, то в словаре это один и тот же ключ:

{1: 'a'}[True]          # 'a'
{1: 'a', True: 'b'}     # {1: 'b'} — ключ один, значение перезаписано

Тот же эффект в set: {1, True} — это множество из одного элемента.

Глубже. Исторически bool появился только в Python 2.3 (PEP 285), и наследование от int выбрали ради обратной совместимости — код, который уже использовал 1/0 как истину и ложь, должен был продолжать работать.

Подвох. Дальше bool унаследовать нельзя — class MyBool(bool): pass падает с TypeError: type 'bool' is not an acceptable base type. CPython намеренно запрещает наследование от bool, чтобы сохранить гарантию, что существуют ровно два экземпляра — True и False.


Что возвращают and и or?

Коротко. Не True/False, а один из операндов. Оба оператора ленивые: вычисляют правую часть, только если это нужно для результата.

'x' and 'y'    # 'y'   — оба истинны, вернулся последний
'' or 'def'    # 'def' — левый ложен, вернулся правый
0 or []        # []    — оба ложны, вернулся последний
  • a and b — если a ложен, возвращает a, иначе b.
  • a or b — если a истинен, возвращает a, иначе b.
  • not a — единственный из трёх, кто всегда возвращает настоящий bool.

Отсюда идиома «значение по умолчанию»: name = user_input or "аноним".

Подвох. У этой идиомы есть ловушка: она подменит любое ложное значение, а не только пустое. count = value or 10 превратит переданный 0 в 10. Когда важно отличить «не передали» от «передали ложное», нужна явная проверка if value is None.

Глубже. Ленивость — не оптимизация, а часть семантики: на неё опираются конструкции вроде if obj is not None and obj.field, где правая часть упадёт, если левая ложна. Подробнее о том, что считается истинным, — в разделе Truthy and Falsy.


← str · 🏠 Домой · Область видимости →