Автор: CoolPython
Методы с двойным подчеркиванием в начале и в конце, например, __eq__
, __hash__, __init__
, в Python называют магическими методами. Их назвали так потому, что они добавляют магию в поведение класса.
Например, метод __init__
неявно вызывается при инициализации объекта:
Foo: def __init__(self, a, b): self.a = a self.b = b foo = Foo(7, 9) # вызывается __init__ print(foo.a, foo.b) # 7, 9
Но сегодня я хочу поговорить о магичесом методе __bool__
. В тех классах, где этот метод определен, он сообщает интерпретатору, как оценить булево значение произвольного объекта.
Зачем нам это? Это нестареющая классика: чтобы проверить словарь или список на непустоту, начинающие часто используют стиль, как в C++:
if len(a) != 0: pass
В то время как PEP8 рекомендует делать просто:
if not a: pass
И это работает ровно потому, что в момент if a
: вызывается метод __bool__
класса список.
Для пользовательских объектов, где __bool__
не перегружен, по умолчанию возвращается True
.
if foo: print(True) else: print(False) # True
Но если добавить
Foo: def __init__(self, a, b): self.a = a self.b = b def __bool__(self): return False
То поведение изменится:
if foo: print(True) else: print(False) # False
Кстати, в случае, если метода __bool__
в классе нет, то интерпретатор будет искать метод __len__
(длина). Поведение такое же: если __len__
возвращает 0, то логическое значение оценивается как False
.
Что с этим делать? Помнить, что falsy (значения, которые оцениваются как False
) в Python это:
- пустые словари {},
- списки [],
- кортежи (),
- множества set(),
- строки «»,
- пустые
range(0)
, - нули любого численного типа: 0, 0.0, 0j
- константы
None
и собственноFalse
А truthy значения это:
- любые пользовательские объекты по умолчанию
- непустые словари, множества, строки, списки, …
- константа
True
И писать проверку на непустоту красиво:
not a: pass