Для большинства начинающих программистов 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
применяется при необходимости управления определенным контекстом и чаще всего востребована при работе с файлами. Контекстный менеджер автоматически закрывает файл в момент выхода из контекста.
Читайте также:
- Как установить несколько версий Python в WSL2 и управлять ими
- Классы данных в Python и их ключевые особенности
- Создание простой нейронной сети на Python
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Yong Cui: 3 Seemingly Simple Python Features That Confuse Beginners