Компьютерная математика II

Дисциплина для студентов 1-го курса специальности «Компьютерная математика и системный анализ» ММФ БГУ

Тема 3. Операторы в Python

доц. Лаврова О.А., кафедра дифференциальных уравнений и системного анализа (ауд. 329)

март, 2023

Оператор -- это один из способов указания действий при выполнении программы

В языке Python определены следующие операторы: оператор присваивания =, оператор выбора if, операторы цикла while и for, break, continue, оператор-заполнитель pass, оператор удаления переменной del, оператор определения функции def, операторы выхода из функции return, yield, и yield from, операторы объявления global иnonlocal, оператор импортирования модуля import, оператор определения класса class, операторы для обработки исключений assert, raise, try, with.

3.1 Cинтаксические правила

Операторы в Python делятся на несоставные и составные операторы. Составной оператор — это оператор, в который вложены другие операторы и выражения.

Синтаксические правила для несоставного оператора

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

Несколько несоставных операторов и/или выражений можно помещать в одну строку кода, разделяя их символом точка с запятой ;

Для читабельности кода рекомендовано размещать по одному несоставному оператору в строке

Код, содержащий круглые (), квадратные [] или фигурные {} скобки, может занимать несколько строк. Многострочный оператор/выражение со скобками не закончится до тех пор, пока не достигнет закрывающей скобки из пары. Отступы в строках продолжения роли не играют, хотя строки рекомендовано выравнивать ради читабельности

Примеры из PEP 8 (руководство по стандартам стиля кодирования на Python https://www.python.org/dev/peps/pep-0008/) корректного выравнивания многострочного кода при определении и вызове функции:

foo = long_function_name(var_one, var_two,
                         var_three, var_four)

def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

foo = long_function_name(
    var_one, var_two,
    var_three, var_four)

При написании многострочного кода следует использовать круглые скобки ()

Альтернативным синтаксисом для написания многострочного кода является использование символа обратной косой черты \ в конце каждой строки кода

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

Синтаксические правила для составного оператора

Составной оператор — это оператор, в который вложены другие операторы и выражения.

Составной оператор имеет следующий вид:

Строка заголовка:

Тело оператора в виде вложенного блока операторов и выражений

Строка заголовка составного оператора должна заканчиваться символом двоеточие :. Отсутствие символа двоеточие : в конце строки заголовка составного оператора является наиболее распространенной ошибкой в Python.

Тело составного оператора записывается с отступом относительно строки заголовка оператора. Отступ — это пробельные символы (пустое пространство) слева от кода. Операторы и выражения вложенного блока должны быть смещены на одинаковое расстояние вправо

Фигурные скобки {} вокруг вложенного блока НЕ нужны

Для отступа можно использовать либо пробелы, либо табуляции. В отдельном блоке используйте либо пробелы, либо табуляции, но не то и другое одновременно. Общепринято использовать отступ в 4 пробела или 1 табуляцию.

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

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

Старайтесь выравнивать код в ЛЮБОМ блочно-структурированном языке программирования для отражения логической структуры кода в целях читабельности кода

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

Если тело составного оператора состоит только из выражений или несоставных операторов, то тело составного оператора может быть записано в строке заголовка оператора после символа двоеточие

Рекомендации по оформлению кода

PEP 8 — руководство по стандартам стиля кодирования на Python, см. https://www.python.org/dev/peps/pep-0008/ (2001, изменения в 2013)

Перевод PEP 8, см. например, https://pythonworld.ru/osnovy/pep-8-rukovodstvo-po-napisaniyu-koda-na-python.html#section-2

3.2 Оператор-заполнитель

Оператор pass не выполняет действий и называется оператором-заполнителем. Он часто применяется для создания пустого вложенного блока составного оператора

Оператор pass может использоваться для обозначения места в коде, подлежащего заполнению в будущем

В Python З.Х в любом месте кода, где может находиться оператор/выражение/объект, разрешено указывать символ многоточие .... Многоточие синтаксически заменяет оператор-заполнитель pass и объект-заполнитель None

3.3 Операторы присваивания

Явное присваивание

Явное присваивание в Python выполняется с помощью оператора присваивания =. Слева от оператора присваивания указываются переменные (имена), справа — выражения. В процессе выполнения явного присваивания вычисляются значения выражений, и полученные объекты связываются с указанными переменными.

После выполнения оператора присваивания переменная хранит ссылку на объект: переменная (имя) -> объект (значение выражения)

Синтаксические формы оператора присваивания

В Python существует пять синтаксических форм явных присваиваний:

Базовое присваивание

Базовое присваивание связывает одну переменную, стоящую слева от оператора присваивания =, с одним объектом, представляющим результат вычисления выражения, стоящего справа от оператора присваивания

Присваивание последовательностей

Оператор присваивания последовательностей имеет вид:

список или кортеж переменных (имен) = последовательность

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

Оператор присваивания последовательностей является позиционным оператором. У последовательностей, стоящих в левой и правой частях, связываются элементы, стоящие на одинаковых позициях. В результате для каждого i-го элемента последовательности определена ссылка на объект:

переменная(имя)i -> объект(значение выражения)i.

Следует отметить, что количество элементов последовательностей левой и правой частей должно совпадать.

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

Распространенный кодовый трюк в Python для обмена значениями двух переменных без использования дополнительной переменной на основе присваивания последовательностей

Слева от оператора присваивания может стоять кортеж или список

var1, var2, ..., varN = obj1, obj2, ..., objN

[var1, var2, ..., varN] = obj1, obj2, ..., objN

В правой части оператора присваивания может стоять любой итерируемый объект

Расширенное присваивание последовательностей

Слева от оператора присваивания можно использовать одиночную переменную, отмеченную звездочкой, *var для указания расширенного присваивания последовательностей. В этом случае переменной var, отмеченной звездочкой, присваивается список, в котором собраны все элементы последовательности, не присвоенные остальным переменным

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

Кодовый трюк в Python на основе расширенного присваивания последовательностей для получения первого и остальных объектов последовательности или начальных и последнего объектов последовательности

Групповое присваивание

При групповом присваивании var1 = var2 = ... = varN = obj переменные var1, var2, ..., varN ссылаются на один и тот же объект obj

При присваивании последовательностей переменные ссылаются на разные объекты

Операторы дополненного присваивания

Оператор дополненного присваивания имеет вид:

a operation= b

и указывает следующую последовательность действий: cначала вычисляется выражение a operation b, затем полученный объект(значение выражения) связывается с переменной a, т.е. а -> a operation b. Всего существует 12 операторов дополненного присваивания

Неявное присваивание

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

Виды неявных присваиваний:

Пространство имен

В Python важным является место в программе, где переменной присваивается значение.

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

Пространство имен объекта содержит ВСЕ атрибуты объекта.

При присваивании вида obj.x = value создается или изменяется переменная x в пространстве имен объекта obj.

Переменная, которой выполнено присваивание внутри функции (внутри оператора def), ассоциируется или связывается с пространством имен данной функции.

Переменная, которой выполнено присваивание внутри класса (внутри оператора class), ассоциируется или связывается с пространством имен данного класса.

Переменная, которой выполнено присваивание в модуле (не внутри функции или класса), ассоциируется с пространством имен модуля.

Даже если при присваивании переменные задаются одинаковыми именами, присваивание значений в разных местах программы (внутри модуля, внутри функции, внутри класса, внутри метода класса) делает все переменные уникальными

Вызов встроенной функции dir() без аргументов позволяет просмотреть пространство имен, соответствующее местоположению вызова функции dir()

Удаление переменной

Оператор del удаляет переменную, созданную ранее явным или неявным присваиванием. Удаление переменной означает как удаление имени переменной, так и удаление ссылки на объект, с которым переменная была связана.

При удалении переменной объект, на который ссылается переменная, не удаляется. Объект удаляется только в том случае, если при удалении переменной удаляется последняя ссылка на объект. Это приводит к автоматической очистке области памяти, где располагается этот объект, так как ни одна переменная в коде на него больше не ссылается.

3.4 Оператор выбора

Оператор if используется для выбора варианта кода на основе результатов проверки условий.

Синтаксический шаблон составного оператора if:

if условие 1:

    Вложенный блок 1 

elif условие 2: $\color{green}{\text{# (необязательная конструкция; может быть несколько)}}$

    Вложенный блок 2

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 3

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

Строки заголовков оператора if и конструкций elif и else связываются друг с другом выравниванием с одинаковыми отступами.

Тернарное выражение if-else

Булевые операции

Для построения условных выражений можно использовать булевые операции and, or, not

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

При выполнении операции or вычисляются слева направо булевые значения операндов и возвращается первый истинный объект, если он найден, или последний операнд в противном случае. Выполнение операции останавливается на первом найденном истинном объекте. Это называют укороченной оценкой.

3.5 Оператор сопоставления

Оператор сопоставлений match появился в версии Python 3.10. Оператор match используется для выбора варианта кода на основе сопоставления объекта с шаблонами.

match obj:

case pattern 1: 

        Вложенный блок 1   
...

case pattern N: 

        Вложенный блок N

case _:
        Вложенный блок N+1

Объект obj последовательно сравнивается с шаблонами pattern 1, pattern 2 до pattern N. При соответствии объекта obj шаблону pattern i выполняется соответствующий Вложенный блок i и действие оператора match завершается. Шаблону _ соответствует ЛЮБОЙ объект.

Ознакомьтесь с результатами выполнения следующих примеров в версии Python 3.10 и выше

В случае, если значение language не совпадает с 'russian', тогда происходит неявное присваивание name=language и выполняется соответствующий вложенный блок print(f'Hello in {name}').

3.6 Операторы цикла

В Python определены два оператора цикла: for и while

Цикл на основе оператора for является простым и эффективным способом прохода по элементам последовательности (итерируемого объекта) и выполнения блока кода для каждого элемента по очереди.

Цикл на основе оператора while представляет собой наиболее универсальный инструмент для организации циклов; он не ограничивается проходом по последовательности, но в целом требует написания большего объема кода и выполняется медленнее, чем цикл for

В Python существуют также неявные концепции организации циклов:

Включения выполняются со скоростью кода на языке С внутри интерпретатора, которая гораздо выше, чем скорость выполнения байт-кода циклов for и while внутри PVM

Оператор while

Синтаксический шаблон составного оператора while:

while условие:

    Вложенный блок 1 

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

while условие:

    Вложенный блок 1 

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

Вложенный блок 1 может содержать операторы break и continue. Оператор break завершает выполнение всей структуры повторения и осуществляет переход за пределы заключающего оператора цикла. Оператор continue прерывает выполнение текущей итерации цикла и осуществляет переход на выполнение следующей итерации этого цикла. Операторы break и continue используются только в циклах.

while условие:

    Вложенный блок 1 

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

Вложенный блок 2 выполняется один раз и только в том случае, если выход из цикла произошел нормально, то есть Вложенный блок 1 НЕ закончился выполнением оператора break

Совместное использование while и break пропускает Вложенный блок 2 конструкции else, что предлагает структурированный способ обработки ситуации с неудавшимся поиском в цикле

Конструкция else цикла while является особенностью Python и не поддерживается в других языках программирования

Оператор for

Синтаксический шаблон составного оператора for:

for element in sequence:

    Вложенный блок 1

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

for element in sequence:

    Вложенный блок 1

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

Переменной цикла element последовательно неявно присваиваются объекты из последовательности sequence слева направо, пока не будет достигнут конец последовательности

for element in sequence:

    Вложенный блок 1

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

Вложенный блок 1 может содержать операторы break и continue. Оператор break завершает выполнение всей структуры повторения и осуществляет переход за пределы заключающего оператора цикла. Оператор continue прерывает выполнение текущей итерации цикла и осуществляет переход на выполнение следующей итерации этого цикла. Операторы break и continue используются только в циклах.

for element in sequence:

    Вложенный блок 1

else: $\color{green}{\text{# (необязательная конструкция)}}$

    Вложенный блок 2

Вложенный блок 2 выполняется один раз и только в том случае, если выход из цикла произошел нормально, то есть Вложенный блок 1 НЕ закончился выполнением оператора break

Совместное использование for и break пропускает Вложенный блок 2 конструкции else, что предлагает структурированный способ обработки ситуации с неудавшимся поиском в цикле

Конструкция else цикла for является особенностью Python и не поддерживается в других языках программирования

Проход по КЛЮЧАМ словаря с помощью цикла for можно осуществить двумя способами, когда последовательностью для прохода в цикле является словарь либо результат вызова словарного метода keys

Для прохода по ЗНАЧЕНИЯМ словаря с помощью цикла for необходимо в качестве последовательности для прохода в цикле использовать результат вызова словарного метода values

Для одновременного прохода по КЛЮЧАМ и ЗНАЧЕНИЯМ словаря с помощью цикла for необходимо в качестве последовательности для прохода в цикле использовать результат вызова словарного метода items

Python предоставляет возможность прохода по строкам файла в цикле for для файлового объекта, не вызывая метод построкового чтения readline

Запомните, что проход в цикле по файловому объекту можно сделать только один раз.

Совет: всякий раз, когда это возможно, применяйте цикл for вместо цикла while

Замечание: не используйте оператор присваивания = в заголовке циклов while

Совет: не используйте вызовы range в циклах for кроме крайних случаев

3.7 Функция вывода

print в Python З.Х является встроенной функцией, в более ранних версиях print был оператором.

Функция print обычно вызывается в отдельной строке, так как она возвращает None.

В общем случае функции, которые возвращают None, рассматриваются как разновидности операторов.

Назначение и синтаксис функции print

print(obj1, obj2, ...[, sep=' '] [, end='\n'][, file=sys.stdout][, flush=False])

Функция print выводит в поток данных file строковые представления одного или большего числа объектов obj1, obj2, ..., которые при выводе разделяются строкой sep. За строковыми представлениями объектов obj1, obj2, ... следует строка end. Буферизированный вывод сбрасывается или нет согласно значению аргумента flush.

print(obj1, obj2, ...[, sep=' '] [, end='\n'][, file=sys.stdout][, flush=False])

По умолчанию функция print записывает произвольные объекты в стандартный поток вывода sys.stdout, автоматически добавляя к объектам некоторое форматирование, разделяя объекты символом пробела и добавляя в конце строки вывода управляющий символ перехода на новую строку. При вызове функции print преобразовывать объекты в строки не требуется в отличие от методов записи файловых объектов write и writelines. При вызове функции print без аргументов в поток стандартного вывода записывается символ новой строки \n.

print(obj1, obj2, ...[, sep=' '] [, end='\n'][, file=sys.stdout][, flush=False])

В Python З.Х указание аргумента file при вызове функции print отправляет строковые представления объектов методу write файлового объекта, указанного в качестве значения аргумента file.

Последующие вызовы функции print продолжают выводить объекты в стандартный поток вывода