Автор: 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

