Python для новичков: логические операторы, выражения присваивания и управление контекстом

Jenny V
NOP::Nuances of Programming
5 min readMay 7, 2021

Для большинства начинающих программистов Python стал отличной стартовой площадкой в мир разработок. Большинство же тех, кто уже владеет каким-либо другим языком программирования, подумывают о переходе на него, учитывая его обширные возможности в машинном обучении, обработке данных и других областях.

По своей сути Pyhton прост и понятен. Однако есть в нем функциональности, которые могут озадачить новичков. В статье мы рассмотрим несколько таких примеров.

1. Логические операторы: and, or

При создании инструкции if…else… мы передаем проверяемое условие. Если условие оценивается как True, выполняется блок if. В случае же его вычисления как False, запускается блок else.

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

Такие составные условия вычисляются напрямую, вследствие чего их можно использовать как тернарные выражения. Рассмотрим примеры:

>>> number = 5 or 4
>>> number
5
>>> text = "" or "Hello, World!"
>>> text
'Hello, World!'

Как видим, в обоих примерах выводится первый не ложный объект. А что вы скажете относительно следующего выражения?

empty_string = ""
empty_list = []
what = empty_string or empty_list

При выполнении этих строк кода вы обнаружите, что what окажется empty_list. Обсудим это позже, а пока обратимся к примерам с логическим оператором and и посмотрим, насколько они вам понятны:

>>> number1 = 3 and 5
>>> number1
5
>>> text1 = "Hello" and "" and "World"
>>> text1
''
>>> text2 = "Hello" and "World" and "!"
>>> text2
'!'

В Python такие составные условные инструкции следуют правилу сокращенных вычислений. В случае с операцией and поиск будет направлен на первое ложное значение. При обнаружении такового вычисление прекращается, а само ложное значение возвращается, как например переменная text1 в вышеуказанном фрагменте кода. Если же такое значение не обнаружено, то возвращается последний элемент, как в примерах с переменными number1 и text2.

В случае с операцией or поиску подлежит первое истинное значение. При его обнаружении вычисление прекращается, а само истинное значение возвращается, как в примерах с переменными number и text. Если же такое значение не найдено, то возвращается последний элемент, как в ситуации с переменной what.

2. Выражение присваивания

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

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

>>> numbers = [1, 2, 3, 4]
>>> eval(str(numbers))
[1, 2, 3, 4]
>>> eval("numbers = [1, 2, 3, 4]")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<string>", line 1
numbers = [1, 2, 3, 4]
^
SyntaxError: invalid syntax

В Pyhton 3.8 были добавлены выражения присваивания, которые позволяют наделить особый вид инструкции присваивания характеристиками выражений. По сути, мы можем присвоить объект переменной (компонент присваивания), и в то же время она будет вычислена в значение (компонент выражения). Данная функциональность предполагает применение нового, так называемого “моржового оператора” — :=. Приведем пример:

>>> (numbers1 := [1, 2, 3])
[1, 2, 3]
>>> eval("(numbers2 := [2, 3, 4])")
[2, 3, 4]

Обратите внимание, что этот пример не имеет практической значимости, а пара круглых скобок обусловлена требованиями синтаксиса, поскольку на верхнем уровне используется выражение присваивания. Рассмотрим пример большей практической направленности, не требующий круглых скобок.

Допустим, у нас есть список чисел, и нам необходимо вычислить нарастающую сумму, которая сохраняется в объекте списка. Воспользуемся функцией accumulate в модуле itertools, как показано в примере:

>>> # Список чисел для вычисления суммы 
>>> numbers = [1, 2, 3, 4]
>>>
>>> # Вычисление накопительной суммы
>>> from itertools import accumulate
>>> list(accumulate(numbers))
[1, 3, 6, 10]

Есть еще одно решение с применением выражения присваивания, которое представлено ниже:

>>> total = 0
>>> [total := total + x for x in numbers]
[1, 3, 6, 10]

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

3. Управление контекстом: with

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

with open("some_file.txt") as file:
text_data = file.read()

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

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

# 1. Открываем файл 
file = open("some_file.txt")

# 2. Выполняем операции с файлом
text_data = file.read()

# 3. Закрываем файл
file.close()

Как видим, для работы с файлом требуется его открыть и закрыть. Закрытие файла необходимо, чтобы сохранить все обновления на случай его использования в другом месте.

Назначение инструкции with состоит в выполнении этой стандартной процедуры за нас. Точнее говоря, файл автоматически закрывается после выхода из инструкции with. Обратимся к примеру:

>>> file0 = open("file0.txt", "w")
>>> file0.write("some random data")
16
>>> print("Is the file0 closed?", file0.closed)
Is the file0 closed? False
>>> with open("file1.txt", "w") as file1:
... file1.write("some random data")
...
>>> print("Is the file1 closed?", file1.closed)
Is the file1 closed? True

Выход из инструкции with приводит к автоматическому закрытию открытого файла, что очень удобно.

Заключение

В статье были рассмотрены 3 функциональности Python, которые могут показаться сложными для новичков. Надеюсь, теперь они стали более понятными. Подведем краткие итоги.

1.При наличии составных условных инструкций Python выполняет сокращенные вычисления. В случае с операцией and возвращается первое ложное значение или последний элемент. В случае с операцией or возвращается первое истинное значение или последний элемент.

2. Выражения и инструкции отличаются друг от друга. Инструкция присваивания не производит значение, тогда как выражение присваивания присваивает переменную и одновременно с этим вычисляет значение.

3. Инструкция with применяется при необходимости управления определенным контекстом и чаще всего востребована при работе с файлами. Контекстный менеджер автоматически закрывает файл в момент выхода из контекста.

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен

--

--