Магические методы и пустые списки Методы с двойным подчеркиванием в начале и в конце, например,
__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
#magic #dunder #bool
@pro_python_code