Share This
Связаться со мной
Крути в низ
Categories
//Используем объекты вместо True и False — truthy и falsy значения в Python

Используем объекты вместо True и False — truthy и falsy значения в Python

20.09.2020Category : Python

Адаптированный перевод «Truthy and Falsy Values in Python: A Detailed Introduction»

Значения вместо булевых переменных

В Python, как и в других языках, есть логический тип переменных bool, который имеет всего два значения: True (истина) и False (ложь). Его возвращают логические операторы (например сравнение чисел или проверка присутствия элемента в списке), и именно этот тип обычно используется в if и while. Тем не менее, явно использовать bool или операторы необязательно: существуют правила, по которым значение любого типа приводится к True или False.

Прим. пер. По-английски это называется truthy и falsy, то есть «примерно-но-не-совсем-истинные», «истинноватые» значения. Общепринятого русского перевода нет, но в этой статье под истинным или ложным значением объекта всегда подразумеваются именно эти штуки, а булевы значения везде названы True и False.

Вот как это работает:

>>> a = 5  >>> if a:     print(a) # Вывод 5  >>> a = 0  >>> if a:     print(a)  # Ничего не выводится 

Булев контекст

Любое значение в Python при необходимости может интерпретироваться как True или False в соответствии с правилами языка. Об этом написано и в документации:

Любой объект может быть протестирован на истинность и использован в условиях if и while, а также как операнд булевых операций (and, or, not).

Если объект используется таким образом, то он находится в булевом контексте. Грубо говоря, это такое место в коде, которое требует от объекта значения либо True, либо False.

В булевом контексте может использоваться как переменная, так и выражение. Если используется выражение, значит, оценивается истинность его результата.

Объекты, которые приравниваются к False

Последовательности и коллекции

  • пустой список: [];
  • пустой кортеж: ();
  • пустой словарь: {};
  • пустое множество: set();
  • пустая строка: «»;
  • пустой диапазон: range(0).

Нули любых численных типов

  • целочисленный ноль: 0;
  • ноль с плавающей точкой: 0.0;
  • комплексный ноль: 0j.

Константы

  • None;
  • False.

Объекты, которые приравниваются к True

Согласно документации:

По умолчанию любой объект имеет истинное значение.

В частности, истинными являются:

  • все непустые последовательности и коллекции (списки, кортежи, словари, множества, диапазоны и строки);
  • все ненулевые числа;
  • True.

Функция bool()

С помощью этой функции можно проверить истинность или ложность любого значения. Согласно документации, она:

Возвращает булево значение, т. е. либо True, либо False. Аргумент x конвертируется с использованием стандартной процедуры проверки истинности.

Например:

>> bool(5) True >>> bool(0) False 

Передавать этой функции можно как значение, так и содержащую его переменную.

Зачем это нужно?

Преимущество истинных и ложных значений в том, что они позволяют сделать код кратким и понятным. Вот два примера:

Пример 1, с сообщением об ошибке

Допустим, у нас есть функция print_even(), которая принимает в качестве аргумента список или кортеж чисел и печатает его чётные элементы. Если список пустой, то выводится сообщение:

def print_even(data): 	if len(data) > 0: 		for value in data: 			if value % 2 == 0: 				print(value)  	else:  		print("Пустой список в аргументе") 

Обратите внимание на эту строчку:

if len(data) > 0:

Её можно сократить до:

if data:

Если список пустой, data имеет ложное значение. Если он не пустой (то есть его длина больше нуля), то истинное. Тот же результат достигается меньшим количеством кода:

def print_even(data): 	if data: 		for value in data: 			if value % 2 == 0: 				print(value)  	else:  		print("Пустой список в аргументе") 

Пример 2, с исключением

Можно использовать истинные/ложные значения, чтобы выбросить исключение, если аргумент некорректен.

>>> def print_even(data):  	if not data: 		raise ValueError("The argument data cannot be empty")  	for value in data: 		if value % 2 == 0: 			print(value)

Если список data пустой:

  • data имеет ложное значение, эквивалентное False;
  • поэтому not data эквивалентно not False, то есть True;
  • поэтому условие if истинно;
  • поэтому бросается исключение.

Если список не пустой:

  • data имеет истинное значение, эквивалентное True;
  • поэтому not data эквивалентно not True, то есть False;
  • поэтому условие if ложно;
  • поэтому исключение не бросается.

Истинные и ложные значения произвольных объектов

Если вы хотите, чтобы у ваших объектов были не только истинные значения, можно добавить к классу метод __bool__() и задать в нём правила, по которым будет определяться истинность или ложность объекта.

Документация:

По умолчанию объект считается истинным, если его класс не определяет метод __bool__, возвращающий для объекта False, или метод __len__, возвращающий для него ноль.

Например, у нас есть вот такой класс:

>>> class Account: 	 	def __init__(self, balance): 		self.balance = balance 

Поскольку у него нет специальных методов, все объекты этого класса имеют истинное значение:

>>> account1 = Account(500) >>> bool(account1) True >>> account2 = Account(0) >>> bool(account2) True 

Это можно исправить, добавив __bool__():

>>> class Account: 	def __init__(self, balance): 		self.balance = balance 		 	def __bool__(self): 		return self.balance > 0 

Теперь объект имеет истинное значение, пока на счету больше нуля. При нулевом или отрицательном балансе значение будет ложным.

>>> account1 = Account(500) >>> bool(account1) True >>> account2 = Account(0) >>> bool(account2) False 

Если у класса нет метода __bool__(), но есть метод __len__(), то истинность объекта определяется истинностью того, что возвращает __len__().

Программист

«ООО «ОЛКОН»», Самара, от 30 000 до 90 000 ₽

tproger.ru Вакансии на tproger.ru

Вот так работает механизм, позволяющий использовать любые объекты в качестве булевых. С его помощью можно сделать код проще и понятнее; важно только не забывать осмысленно называть переменные — какое-нибудь pabotat() if cnucok_2 else He_pabotat() никуда не годится что с булевским контекстом, что без него.

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Honor Cup, бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации

  • 16 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close