Книга: Как устроен Python. Гид для разработчиков, программистов и интересующихся
Назад: 11. Строки и методы
Дальше: 13. Условия и отступы

12. Комментарии, логические значения и None

В этой главе рассматриваются комментарии, логические значения и None. Комментарии делают ваш код более понятным. Логические значения и тип None очень часто используются в коде Python.

12.1. Комментарии

Комментарии не являются типом, потому что Python их игнорирует. Они должны что-то напомнить или пояснить программисту. Существуют разные мнения по поводу того, как нужно писать комментарии, их цели и полезности. Спектр мнений широк: от тех, кто против любых комментариев, до тех, кто комментирует почти каждую строку кода. Если вы участвуете в проекте, старайтесь соблюдать принятую в нем схему комментирования. Как правило, хороший комментарий должен объяснять почему, а не как (для ответа на вопрос как должно быть достаточного самого кода).

Чтобы создать комментарий в Python, начните строку с символа #. Все, что следует после этого символа, игнорируется:

>>> # This line is ignored by Python

Также комментарий может располагаться в конце строки:

>>> num = 3.14 # PI

СОВЕТ

Комментарии также используются для временной блокировки кода в процессе редактирования. Если ваш редактор поддерживает такую возможность, иногда бывает проще закомментировать код вместо того, чтобы удалять его полностью.

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

В других языках поддерживаются многострочные комментарии, но в Python их нет. Единственный способ создать комментарий из нескольких строк — начинать каждую строку с #.

СОВЕТ

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

12.2. Логические значения

Логические значения представляют понятия «истина» (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

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

12.3. None

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 должна осуществляться явно.

12.4. Итоги

В этой главе вы узнали о комментариях в языке Python. Комментарии начинаются с символа #, а все последующие символы до конца строки игнорируются. Многострочные комментарии не поддерживаются.

Также в этой главе обсуждаются значения True, False и преобразование к логическому типу. Многие значения интерпретируются как True в логическом контексте (например, при использовании в команде if). Как False интерпретируются нули, None и пустые последовательности.

Глава завершается описанием объекта None. Это одиночный объект, обозначающий переменные, значение которых должно быть присвоено в будущем. Он также является результатом функции, которая не возвращает значение явно.

12.5. Упражнения

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 не является названием автомобиля.)

Назад: 11. Строки и методы
Дальше: 13. Условия и отступы