В языке Python поддерживаются следующие комбинированные операторы присваивания, которые в некоторых случаях упрощают запись кода:
Операция | Эквивалент |
x += y | x = x + y |
x -= y | x = x - y |
x *= y | x = x * y |
x /= y | x = x / y |
x //= y | x = x // y |
x **= y | x = x ** y |
x %= y | x = x % y |
x &= y | x = x & y |
x |= y | x = x | y |
x ^= y | x = x ^ y |
x>>= y | x = x>>y |
x <<= y | x = x << y |
Работа с файлами
Пример чтения файла и вывода его на экран
f = open("data.txt", "rb")
R=f.readlines()
print (R)
f.close()
XML
def export_xml_etree(filename):
root = xml.etree.ElementTree.Element("Cycle")
for i in Процесс():
element = xml.etree.ElementTree.Element("Process",
m=str(i[0]),
n=str(i[1]))
root.append(element)
tree = xml.etree.ElementTree.ElementTree(root)
Пользовательские функции
Процедуры и функции относятся к общему понятию подпрограммы. Подпрограммы – важный элемент структурного программирования.
Подпрограмма - это блок программного кода, к которому можно обращаться из различных точек программы. Подпрограммы создаются либо для упорядочивания структуры программы, либо для автоматизации часто выполняемой последовательности действий с различными исходными данными.
Процедура является частным случаем функции, которая не возвращает никакого значения в качестве результата. Результат работы процедуры может быть как в изменении некоторых глобальных переменных, либо в виде какого-то действия, например, вывод информации на экран. Простейший пример процедуры без исходных данных и возвращаемого результата из языка Паскаль - процедура beep, которая короткий издаёт гудок динамиком.
В современных языках программирования процедуры пишутся как функции без явно возвращаемого результата, или возвращающие не существенный признак успешного выполнения операции.
Создание функции в Python производится с помощью инструкции def, как показано в следующем примере:
def remainder(a, b):
q = a // b
# // – оператор деления с усечением дробной части.
r = a - q*b
return r
Чтобы вызвать функцию, достаточно указать ее имя и следующий за ним список аргументов, заключенный в круглые скобки, например: result = remainder(37, 15). В Python функции легко могут возвращать несколько значений, для чего используется кортеж, как показано ниже:
def divide(a, b):
q = a // b
# Если a и b – целые числа, q будет целым числом
r = a - q*b
return (q,r)
Когда функция возвращает кортеж с несколькими значениями, его легко можно распаковать во множество отдельных переменных, как показано ниже:
quotient, remainder = divide(1456, 33)
Присвоить аргументу функции значение по умолчанию можно с помощью оператора присваивания:
def connect(hostname, port, timeout=300):
# Тело функции
Также имеется возможность передавать функции именованные аргументы, которые при этом можно перечислять в произвольном порядке. Однако в этом случае вы должны знать, какие имена аргументов указаны в определении функции. Например:
connect(port=80, hostname=”www.python.org”)
Когда внутри функции создаются новые переменные, они имеют локальную область видимости. То есть такие переменные определены только в пределах тела функции, и они уничтожаются, когда функция возвращает управление вызывающей программе. Чтобы иметь возможность изменять глобальные переменные внутри функции, эти переменные следует определить в теле функции с помощью инструкции global:
count = 0
...
def foo():
global count
count += 1
# Изменяет значение глобальной переменной count
Следующая строка после инструкции def, если она взята в кавычки, является строкой документации, в которой приводится краткое описание функции:
def movement(self,α=0):
"""Функция для вычисления текущего значения перемещения"""
Python не требует наличия строки документации у функции, но ее стоит определять, тем более, что многие Python IDE используют строки документации для контекстной справки.
Стек вызовов
Стек – это специальная структура данных, взаимодействие с которой производится по специальному правилу LIFO (от англ. Last In First Out – «последним вошел, первым вышел»).
При вызове подпрограммы в стеке вызовов запоминается адрес следующей команды, и управление передаётся к началу подпрограммы. При завершении подпрограммы программа продолжается с команды, следующей за командой вызова и запись из стека удаляется. Если подпрограмма вызывает другую подпрограмму, то её адрес также записывается в стек. Следует учитывать, что переполнение стека вызовов при рекурсии (многократном вызове вложенных функций) может вызвать остановку выполнения программы (на Python) или сбой в работе системы (на языке C).
Рассмотрим пример, где функция f3() вызывает функцию f2(), функция f2() вызывает функцию f1():
def f1():
print ("Входим в процедуру f1()")
#a = 1/0
print ("Выходим из процедуры f1()")
def f2():
print ("Входим в процедуру f2()")
f1()
print ("Выходим из процедуры f2()")
def f3():
print ("Входим в процедуру f3()")
f2()
print ("Выходим из процедуры f3()")
f3()
Вывод программы:
Входим в процедуру f3()
Входим в процедуру f2()
Входим в процедуру f1()
Выходим из процедуры f1()
Выходим из процедуры f2()
Выходим из процедуры f3()
Когда мы входим в процедуру f1(), в стеке вызовов хранятся данные процедур f2() и f3(), поскольку они ещё не закончили свою работу. Освобождается стек в обратном порядке. В процессе выполнения программы стек может разрастаться и опустошаться много раз.
Когда в одной из функций возникает исключение, часто бывает довольно трудно понять, при каких условиях (или при каком наборе параметров) произошел сбой, т.к. одна и та же функция может вызываться из различных мест программы по многу раз. Поэтому для облегчения процесса отладки интерпретатор Питона выводит не только номер строки, где возникло исключение, но и весь стек вызовов на момент возникновения исключения.
Раскомментируем выражение a = 1/0, чтобы в функции f1() было сгенерировано исключение деления на ноль. В результате получим:
Входим в процедуру f3()
Входим в процедуру f2()
Входим в процедуру f1()
Traceback (most recent call last):
File "Пример.py", line 22, in <module>
f3()
File "Пример.py", line 20, in f3
f2()
File "Пример.py", line 16, in f2
f1()
File "Пример.py", line 12, in f1
a = 1/0
ZeroDivisionError: division by zero
После сообщения о начале выполнения функции f1() интерпретатор вывел так называемый traceback («трейсбэк» или, как иногда говорят, просто «трейс»). Traceback содержит не только названия функций из стека вызовов, но и номера строк, из которых был произведен каждый вызов. Кроме номеров указывается еще и название файла с программой, ведь проект может содержать не один модуль. Так что найти и исправить ошибку становится гораздо проще. [2]
Лямбда-функции
Это альтернативный инструкции def способ определения функции. Отличается тем, что записывается в одну строчку. Если функция вызывается один раз, можно не давать ей имени, а сразу записать аргументы после лямбда-выражения. Это удобно для небольших функций и востребовано в функциональном программировании. Название оператора Лямбда заимствовано из теории функционального программирования его первооткрывателя Алонзо Чёрча.
Пример: определим функцию k(T) обычным способом:
def k(T):
return 1.444-1.812e-4*T+5.146e-8*T**2
То же с помощью Лямбда-функции
k= lambda T:1.444-1.812e-4*T+5.146e-8*T**2
После оператора lambda сначала перечисляются аргументы, а после двоеточия следует выражение (тело) функции.
Ещё один пример:
import math
polar= lambda x,y:(math.sqrt(x**2+y**2),math.atan2(x,y))
R,φ=polar(-3,-4)
print (R,φ)
В данном случае функция polarимеет два аргумента xи yи возвращает кортеж из двух значений, который распаковывается в переменные R и φ.
Или то же самое, но не давая функции имени:
R,φ=(lambda x,y:(math.sqrt(x**2+y**2),math.atan2(x,y)))(-3,-4)
print (R,φ)
Или то же самое, передавая результат непосредственно в оператор print ():
print ((lambda x,y:(math.sqrt(x**2+y**2),math.atan2(x,y)))(-3,-4))