В этой главе рассматриваются комментарии, логические значения и None. Комментарии делают ваш код более понятным. Логические значения и тип None очень часто используются в коде Python.
Комментарии не являются типом, потому что Python их игнорирует. Они должны что-то напомнить или пояснить программисту. Существуют разные мнения по поводу того, как нужно писать комментарии, их цели и полезности. Спектр мнений широк: от тех, кто против любых комментариев, до тех, кто комментирует почти каждую строку кода. Если вы участвуете в проекте, старайтесь соблюдать принятую в нем схему комментирования. Как правило, хороший комментарий должен объяснять почему, а не как (для ответа на вопрос как должно быть достаточного самого кода).
Чтобы создать комментарий в Python, начните строку с символа #. Все, что следует после этого символа, игнорируется:
>>> # This line is ignored by Python
Также комментарий может располагаться в конце строки:
>>> num = 3.14 # PI
СОВЕТ
Комментарии также используются для временной блокировки кода в процессе редактирования. Если ваш редактор поддерживает такую возможность, иногда бывает проще закомментировать код вместо того, чтобы удалять его полностью.
Тем не менее перед тем, как передавать код для распространения, закомментированные участки лучше удалить.
В других языках поддерживаются многострочные комментарии, но в Python их нет. Единственный способ создать комментарий из нескольких строк — начинать каждую строку с #.
СОВЕТ
Возможно, у вас появилась соблазнительная мысль создать комментарий из нескольких строк при помощи строки, заключенной в тройные кавычки. Такие конструкции получаются уродливыми и непонятными, не используйте их.
Логические значения представляют понятия «истина» (True) и «ложь» (False). Вы уже видели их в приведенных ранее примерах кода — например, в результате .startswith:
>>> 'bar'.startswith('b')
True
Такие значения можно присваивать переменным:
>>> a = True
>>> b = False
ПРИМЕЧАНИЕ
В языке Python логические значения относятся к классу bool:
>>> type(True)
<class 'bool'>
Бывает полезно преобразовывать другие типы к логическим значениям. В языке Python это можно сделать при помощи класса bool. Впрочем, обычно прямые преобразования типов оказываются излишними из-за неявного преобразования, которое выполняет Python при проверке условных конструкций. При обработке условий это преобразование будет выполнено за вас.
В терминологии Python нередко приходится слышать о «квазиистинном» или «квазиложном» поведении объектов — это означает, что нелогические типы могут неявно вести себя так, словно являются логическими. Если вы не уверены в том, как себя поведет ваш тип, выполните явное преобразование с использованием класса bool.
Для строк пустая строка обладает «квазиложным» поведением, тогда как непустые значения интерпретируются как True:
>>> bool('')
False
>>> bool('0') # Строка содержит 0
True
Так как непустая строка обладает квазиистинным поведением, вы можете проверить, содержит ли строка какие-либо данные. В следующем фрагменте значение name задается в коде, но представьте, что оно должно вводиться пользователем:
>>> name = 'Paul'
>>> if name:
... print("The name is {}".format(name))
... else:
... print("Name is missing")
The name is Paul
Необязательно проверять длину name. Не делайте так:
>>> if len(name) > 0:
... print("The name is {}".format(name))
И так тоже поступать не нужно:
>>> if bool(name):
... print("The name is {}".format(name))
потому что Python вычислит содержимое команды if и преобразует его в логическое значение за вас. Поскольку непустая строка интерпретируется как True, достаточно использовать конструкцию вида
>>> if name:
... print("The name is {}".format(name))
ПРИМЕЧАНИЕ
Встроенные типы int, float, str и bool являются классами. Хотя из-за регистра символов (нижнего) они похожи на функции, на самом деле это классы. В этом легко убедиться вызовом help(str):
>>> help(str)
Help on class str in module builtins:
class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
Здесь проявляется небольшая непоследовательность языка Python: классы, определяемые пользователем, обычно подчиняются правилам PEP8, которые рекомендуют «верблюжий» регистр в именах классов.
Для чисел ноль интерпретируется как False, тогда как другие числа обладают поведением True:
>>> bool(0)
False
>>> bool(4)
True
Хотя явное преобразование функцией bool доступно, обычно оно излишне, потому что переменные неявно преобразуются в логические значения при использовании в условных командах. Например, типы-контейнеры (такие, как списки и словари), не содержащие элементов, обладают «квазиложным» поведением. С другой стороны, при появлении элементов они интерпретируются как «квазиистинные».
СОВЕТ
Будьте внимательны при разборе содержимого, которое должно быть преобразовано в логические значения. Непустые строки интерпретируются как True. Например, неожиданный сюрприз может преподнести строка 'False', которая интерпретируется как True:
>>> bool('False')
True
Ниже приведена таблица квазиистинных и квазиложных значений.
Квазиистинность | Квазиложность |
True | False |
Большинство объектов | None |
1 | 0 |
3.2 | 0.0 |
[1, 2] | [] (пустой список) |
{'a': 1, 'b': 2} | {} (пустой словарь) |
'string' | "" (пустая строка) |
'False' | |
'0' |
СОВЕТ
Не проверяйте логические значения, чтобы узнать, равны ли они True. Если у вас имеется переменная done, содержащая логическое значение, достаточно следующей конструкции:
if done:
# ...
С другой стороны, следующая проверка будет излишней:
if done == True:
# ...
Как и эта проверка:
if bool(done):
# ...
Аналогичным образом, если у вас имеется список и вам потребуется выполнить разные действия для пустого и непустого списка, достаточно будет следующего фрагмента:
members = []
if members:
# Действия, если members
# содержит значения
else:
# Список members пуст
А следующая проверка будет избыточной. Не нужно проверять квазиистинность списка по его длине:
if len(members) > 0:
# Действия, если members
# содержит значения
else:
# Список members пуст
ПРИМЕЧАНИЕ
Если вы хотите определить неявную квазиистинность для объектов, определяемых пользователем, это поведение определяется методом .__bool__. Метод может возвращать True или False. Если этот специальный метод не определен, то метод .__len__ проверяется на ненулевое значение. Если и этот метод не определен, объект по умолчанию интерпретируется как True:
>>> class Nope:
... def __bool__(self):
... return False
>>> n = Nope()
>>> bool(n)
False
Если все это покажется вам непонятным, вернитесь к примеру после того, как прочитаете об этих классах.
None является экземпляром NoneType. В других языках также существуют аналогичные конструкции, такие как nil, NULL или undefined. Присваивая переменной None, вы тем самым показываете, что переменной еще не было присвоено реальное значение. В логическом контексте None интерпретируется как False:
>>> bool(None)
False
ПРИМЕЧАНИЕ
Функция Python при отсутствии команды return по умолчанию возвращает None:
>>> def hello():
... print("hi")
>>> result = hello()
hi
>>> print(result)
None
ПРИМЕЧАНИЕ
None является одиночным (синглетным) экземпляром (то есть в интерпретаторе Python всегда хранится только одна копия None). Идентификатор этого значения всегда остается одним и тем же:
>>> a = None
>>> id(a)
140575303591440
>>> b = None
>>> id(b)
140575303591440
Таким образом, любая переменная, содержащая None, указывает на тот же объект, что и любая другая переменная, содержащая None. Обычно для таких переменных используется проверка тождественности оператором is вместо проверки равенства оператором ==:
>>> a is b
True
>>> a is not b
False
Оператор is работает быстрее == и напоминает программисту, что сравниваются идентификаторы, а не значения. Также выражение is можно поместить в команду if:
>>> if a is None:
... print("A is not set!")
A is not set!
Так как None в логическом контексте интерпретируется как False, также возможно такое решение:
>>> if not a:
... print("A is not set!")
A is not set!
Тем не менее будьте осторожны с другими значениями, которые также интерпретируются как False — такими, как 0, [] или '' (пустая строка). Проверка на None должна осуществляться явно.
В этой главе вы узнали о комментариях в языке Python. Комментарии начинаются с символа #, а все последующие символы до конца строки игнорируются. Многострочные комментарии не поддерживаются.
Также в этой главе обсуждаются значения True, False и преобразование к логическому типу. Многие значения интерпретируются как True в логическом контексте (например, при использовании в команде if). Как False интерпретируются нули, None и пустые последовательности.
Глава завершается описанием объекта None. Это одиночный объект, обозначающий переменные, значение которых должно быть присвоено в будущем. Он также является результатом функции, которая не возвращает значение явно.
1. Создайте переменную age и присвойте ей свой возраст. Создайте другую переменную — old, которая использует условие для проверки того, что вы старше 18 лет. Значение old должно быть равно True или False.
2. Создайте переменную name и присвойте ей свое имя. Создайте другую переменную — second_half, которая проверяет, находится ли первая буква name во второй половине алфавита. Что необходимо для того, чтобы выполнить сравнение?
3. Создайте список names с именами людей в классе. Напишите код, который выводит сообщение 'The class is empty!' или 'Class has enrollments.' в зависимости от того, содержит ли names хоть одно значение. (В этой главе вы найдете подсказки.)
4. Создайте переменную car и присвойте ей None. Напишите код, который выводит сообщение 'Taxi for you!' или 'You have a car!' в зависимости от того, содержит ли car хоть одно значение. (None не является названием автомобиля.)