Процедуры и функции аналогичны программам в миниатюре и имеют общее название — подпрограммы.
Подпрограмма — это часть программы, описывающая некоторый алгоритм, который можно многократно использовать, обращаясь к нему из различных точек программы.
Зачем нужны подпрограммы?
Применение подпрограмм дает возможность уменьшать число повторений одной и той же последовательности операторов, а также конструировать программу как набор отдельных подпрограмм. Это позволяет получить более логичный процесс программирования.
Где располагаются подпрограммы в программе?
В программе описание процедур и функций должно располагаться между разделами переменных и операторов.
Как работает компьютер по программе, имеющую подпрограммы?
Выполнение программы, имеющую подпрограмму, начинается с выполнения основной программы. Как только в программе идет обращение к подпрограмме, данные из основной программы (входные данные) передаются в подпрограмму, которая начинает выполняться. Затем результаты подпрограммы (выходные данные) передаются в основную программу в то место, откуда был сделан вызов подпрограммы, и продолжает выполняться основная программа.
#5 PYTHON: ФУНКЦИИ И ПРОЦЕДУРЫ
Как оформляется подпрограмма?
Подпрограмма оформляется подобно основной программе, т.е. состоит из заголовка, раздела описаний, раздела операторов.
Различие глобальных и локальных переменных?
Все имена, представленные в разделе описаний основной программы, называются глобальными. Они действуют как во всей основной программе, так и в любой подпрограмме. Имена, представленные в разделе описаний подпрограммы, называют локальными. Они действуют только в рамках подпрограммы и недоступны операторам основной программы.
Два вида подпрограмм в Паскале?
В языке Паскаль имеется два вида подпрограмм:
процедура (PROCEDURE), функция (FUNCTION)
Чем процедура похожа на функцию?
И процедура и функция – отдельные программные блоки.
И процедура и функция вызываются по имени из любой части основной программы.
В процедуру или функцию можно передавать фактические параметры (числа, слова и т.п.) для их работы (если они нужны)
После их выполнения продолжается выполнение основной программы с того места, где были вызваны процедура или функция.
Чем процедура отличается от функции?
После выполнения процедура не возвращает никакого результата в основную программу. Она не может быть вставлена внутрь арифметического выражения. Самый простой пример процедуры – СходитьВМузей(). Назад домой вы ничего не принесли .
Функция после выполнения возвращает результат (единственное значение!) в основную программу. Поэтому функцию можно использовать в арифметических выражениях. Самый простой пример функции – КупитьХлеб(деньги). Домой принесли хлеб.
Примечание: Если мы хотим в результате выполнения функции получить несколько значений (а возвращает только одно), то надо использовать подпрограмму и глобальные переменные.
37 Возвращаемое значение функции. Оператор return Python
Оформление процедуры.
PROCEDURE имя (формальные параметры);
раздел описаний
раздел операторов
Вызывается процедура по имени:
имя (фактические параметры);
Фактические и формальные параметры.
С помощью фактических и формальных параметров данные передаются из программы в процедуру и из процедуры в программу. В качестве формальных параметров могут быть только переменные с указанием типа, а в качестве фактических параметров могут быть константы, переменные, выражения без указания их типа. Порядок передачи фактических параметров должен соответствовать порядку формальных параметров, иначе возникнет путаница.
Как это делается:
Допустим, фактические параметры – это числа, с которыми должна работать процедура или функция. При вызове процедуры (функции) эти числа указываются в скобках. Тем самым они передаются телу функции для обработки. Однако процедура напрямую не работает с этими числами (или переменными, содержащими числа – можно их и так передать в функцию).
Процедура присваивает их (значения переменных или числа) своим формальным параметрам – внутренним (локальным) переменным. Функция (процедура) начинает работать со своими локальными переменными.
Результат выполнения передается в основную программу по-разному.
Ещё раз о параметрах процедуры
Процедура может содержать несколько операторов и несколько результатов выполнения. Каждый результат обозначается своим именем. В основной программе после вызова процедуры мы можем пользоваться этими результатами, сохраняя те же имена или давая другие.
Пример. Допустим, вызывается процедура нахождения площади прямоугольника: PLOSH(A,B,S) или PLOSH(3,2.5,S). Переменные А и В содержат значения сторон, которые передаются в процедуру для решения. После решения ответ передается в переменную S. Эту S можно использовать в основной программе, так как она объявлена как глобальная переменная. Это был вызов процедуры.
Понятно, что прежде чем вызывать процедуру, ее нужно описать. В нашем случае заголовок будет выглядеть так:
PROCEDURE PLOSH(dlina, shirina:integer; VAR otvet: integer);
Переменные dlina, shirina, otvet – формальные переменные (внутренние переменные процедуры). Им в соответствие ставятся фактические переменные А, В, S при вызове процедуры. Далее при вызове происходит следующее: значение переменной А присваивается переменной dlina, значение переменной В присваивается переменной shirina, а после всех вычислений значение переменной otvet присваивается переменной S. Таким образом результат из процедуры выходит «наружу», в основную программу.
Параметры процедуры делятся на отдельные виды, но в простых программах чаще всего используются параметры-значения (у нас А, В) и параметры-переменные (у нас S). В формальных параметрах процедуры перед параметрами-переменными ставится слово VAR. Данные этих параметров передаются в обоих направлениях: из программы в процедуру и, наоборот, из процедуры в программу.
В случае переопределения этих данных в процедуре, они все равно доступны программе. Если в процедуре перед формальными параметрами не стоит слово VAR, то такие параметры называются параметрами-значениями. Их можно передавать только в одном направлении: из программы в процедуру. Эти параметры не могут быть результатом выполнения процедуры. Таким образом, параметры-значения могут быть только входными для процедуры, а параметры-переменные как входными, так и выходными.
Пусть имеется процедура:
Procedure summa(a:integer; var b:integer);
Посмотрим, чему будут равны значения А и В в основной программе после выполнения следующих операторов:
Здесь значения А = 5 и В = 5 передаются в процедуру, где вычисляются новые значения А=5+3=8 и В=5+3=8. Новое значение В передается в программу, а значение А – нет. Поэтому в основной программе будем иметь А=5, В=8.
Примеры программ с процедурами.
Пример 1. Вычислить:
Степень находить так: X N = X X X . X
program pr1;
var d,z,m,,a,b,c:integer;
y,y1,y2,y3: real;
var i:integer;
for i:=1 to n do
Пример 2. Среди трехзначных чисел найти такие, в которых сумма факториалов цифр равнялась бы самому числу. (факториал числа – это последовательное произведение чисел, начиная с 1 и до этого числа: 4! = 1*2*3*4)
program pr2;
var a,b,c,i,s1,s2,s3:integer;
procedure faktor(x:integer; var s:integer);
var i:integer;
for i:=1 to x do
for i:=100 to 999 do
if s1+s2+s3=i then writeln (i);
Оформление функций.
Функция, как и процедура, может содержать несколько операторов, несколько входных параметров, но результат ее выполнения только один. Этот единственный результат обозначается именем функции и передается в основную программу. Если нам нужно возвратить больше одного результата, то придется иметь дело с процедурой.
В общем виде функция записывается так:
FUNCTION ИМЯ(список формальных параметров: тип): тип;
Вызывается функция по ее имени с указанием фактических параметров. При этом вызов функции можно делать непосредственно внутри выражения, подобно тому, как используются стандартные встроенные функции, например SIN(X).
Примеры программ с функциями:
Тот же самый пример , но с использованием функции:
program pr1;
var d,z,m,a,b,c:integer;
function step(x,n:integer):real;
var i,w:integer;
for i:=1 to n do
y:=(step (d,a)+step (z,b))/step (m,c);
Пример.
Даны действительные числа S и T. Получить: F(T,-2*S,1.17) + F(2.2,T,S-T),
program pr3;
var y,t,s:real;
function form(a,b,c:real):real;
y:=form(t,-2*s,1.17)+form(2.2,t,s-t);
Пример 4. Даны действительные числа a,b,c. Получить:
program pr4;
var a,b,c,z:real;
function max(x,y:real):real;
var m:real;
if x>y then m:=x else m:=y;
Ещё различие процедур и функций.
Функции являются частным случаем процедур и принципиально отличаются от них тем, что:
1. результат выполнения функции — одно значение, а процедуры — одно или несколько;
2. результат выполнения функции передается в основную программу как значение имени этой функции, а результаты выполнения процедуры — как значения ее параметров.
ЗАДАНИЯ на использование процедур:
Даны координаты вершин треугольника и точки внутри него. Найти расстояние от данной точки до ближайшей стороны треугольника.
1. Нахождение длин сторон (OB, OC,OA,BA,CA,BC). (Процедура dlin)
2. Нахождение площади трех треугольников S1(ABO), S2 (OBC), S3 (OCA). (Процедура pl)
3. Нахождение высот треугольников. (Процедура vis)
4. Сравнение высот (нахождение до ближайшей стороны). (Процедура min)
Проверить результаты выполнения программы по таблице:
Источник: studfile.net
Как функция может «запомнить» результат для следующего использования?
Как создать функцию, которая запоминает возвращенный результат?
char * foo(char * str1, char * str2) < . return bar; >int main() < . foo(a,b); //returns a string foo(NULL,c);//will use the returned above string in the NULL parameter >
Это похоже на то, как работает strtok .
Я полагаю, что глобальная переменная может работать, но, насколько я знаю, это не очень хорошая практика, есть ли другой способ? Работает ли strtok с глобальной переменной?
shinzou 22 Фев 2015 в 21:02
2 ответа
Лучший ответ
Я отвечаю на ваш заголовок: «Как функция может« запомнить »свой результат для следующего использования?». Ваш заголовок подразумевает общий случай, и меня не интересует конкретная функция в теле вашего вопроса.
Во-первых, я хотел бы поблагодарить Python за ключевое слово yield , к сожалению, в C нет такого синтаксического сахара.
Поэтому наиболее правильный ответ — НЕТ, вы не можете сделать это в C, и нет, статика — это не ответ .
Статика не реентерабельна. Иногда лучше просто сказать «нет», «вы не можете этого сделать» — ни на самом деле, ни на языке C, чем рассказывать вам полусырые решения. У C просто нет этой функции, и все.
В Python есть yield , а в C нет. Конец.
Вам нужно будет смоделировать это, используя структуру для хранения состояния.
struct State < . >; Output foo(struct State *state, . ) < . >. foo( foo(
Если вы не хотите делать это правильно, используйте static и потратьте 2-3 дня на выяснение ошибок при попытке вложить вызов функции. strtok укусил людей таким образом.
Обратите внимание , что использование static может сделать функцию не реентерабельной . Будь осторожен:
Output foo(. )
Дополнение
Функции в математическом смысле по определению не имеют состояния. Если у него есть состояние, то это объект, а не функция. Функция со статическим состоянием семантически на самом деле является одноэлементным объектом.
Состояние подразумевает память, а память + методы = объект.
sashoalm 22 Фев 2015 в 18:38
Вот для чего нужно ключевое слово static в языке C. Вроде! Будьте осторожны, см. Правки ниже.
Переменная с классом хранения static будет существовать в течение всего времени существования программы, а не только до конца области объявления:
int foo()
Вернет 1,2,3. при последующих вызовах.
РЕДАКТИРОВАТЬ: Комментаторы, похоже, согласны с тем, что было бы разумно предупредить вас, что static опасен, если вы выполняете параллельный доступ (например, многопоточность), с чем я согласен. Но опять же, вы уже знаете, что глобальные переменные могут быть вредными, так что это может быть не ново, и, учитывая характер вашего вопроса, вы можете не быть в той точке вашей карьеры программирования, где вы выполняете многопоточность. ; если вы это делаете, обратитесь к тому, что знакомит вас с многопоточностью, чтобы узнать о безопасных способах изменения общих состояний (семафоры / мьютексы . ).
EDIT2: это, конечно, опасно не только в многопоточных средах; например, когда две разные функции вызывают foo изнутри и ожидают увидеть свою собственную последовательность 1,2,3. , что-то пойдет не так. Используйте с особой осторожностью.
Итак, наиболее правильный ответ — НЕТ, вы не можете сделать это в C, и нет, статика — это не ответ.
Источник: question-it.com
Инструкции присваивания в Python
- Присваивание в Python и его каноническая форма
- Комбинированные инструкции присваивания
- Позиционное присваивание
- Групповое присваивание одного значения
- Выражения присваивания в Python
- Краткие итоги параграфа
- Вопросы и задания для самоконтроля
Присваивание в Python и его каноническая форма
В Python , как и во многих других языках программирования, каноническая форма операции присваивания имеет вид a = b , где слева от оператора присваивания записывается целевое имя переменной или компонент объекта, а в качестве правого операнда выступает произвольное выражение, которое в результате вычислений дает объект (см. пример №1 ).
Код Результат pythonCodes
# Присвоили выражение. a = 5 + 0.3 # Выведет 5.3. print(a, end=’nn’) # Присвоили список. b = [1, 1, 2] print(b, end=’nn’) # Изменили первый эл-т списка. b[0] = 0 # Выведет [0, 1, 2]. print(b, end=’nn’) # Объявили ф-цию со значением по умолчанию. def my_func(li=[]): return li # Присвоили объект функции. f = my_func # Выведет [0, 1, 2]. print(f(b)) # Присвоили вызов функции. e = my_func(b) # Выведет [0, 1, 2]. print(e)
5.3 [1, 1, 2] [0, 1, 2] [0, 1, 2] [0, 1, 2]
Пример №1. Каноническая форма присваивания.
Как видим, присваивание действительно выполняется достаточно просто. Однако при этом хотелось бы обратить внимание на следующие особенности присваивания в Python :
- Инструкции присваивания всегда сохраняют ссылки на объекты, например, в переменных или в элементах структур данных, и никогда не создают копии присваиваемых объектов. Как следствие, переменные в Python больше напоминают указатели, чем области хранения данных.
- Объявлять переменные заранее нельзя, т.к. интерпретатор создает переменные в момент присваивания им значений (то есть ссылок на объекты). После инициализации, когда имя переменной будет встречаться в выражениях, оно будет автоматически замещаться объектом, на который ссылается данная переменная. Если же интерпретатор встретит в программе неинициализированную переменную, он возбудит исключение вместо того, чтобы вернуть какое-либо значение по умолчанию (такое поведение призвано облегчить поиск ошибок и опечаток в коде).
- Некоторые инструкции пусть и неявно, но тоже выполняют операцию присваивания. Примерами могут служить импорт модуля, определение функции или класса, указание переменной в цикле for или же передача аргументов функции. В любом случае результатом явных или неявных инструкций присваивания будет связывание имен с ссылками на объекты.
Ну, и в конце пункта еще раз напомним, что в программировании знак равно ( = ) обычно означает не равенство двух величин, а присваивание значения переменной. Если же нужно указать на равенство двух значений, то используется комбинация символов из двух знаков равно ( == ).
Комбинированные инструкции присваивания
В дополнение к базовой инструкции присваивания в Python имеется и целый ряд комбинированных инструкций присваивания, которые объединяют операцию присваивания с другой операцией. В общем виде инструкцию присваивания с комбинированным оператором x operator= y можно считать сокращенной записью инструкции x = x operator y . Например, x += y является сокращенной записью инструкции присваивания x = x + y , в которой к значению переменной x прибавляется значение переменной y , а результат присваивается переменной x (см. пример №2 ).
Код Результат pythonCodes
# Присвоили начальное значение. a = 3 print(‘a = 3 ->’, a, end=’nn’) # Теперь a == 9, что равнозначно a = a + 6. a += 6 print(‘a += 6 ->’, a, end=’nn’) # Теперь a == 18, что равнозначно a = a*2. a *= 2 print(‘a *= 2 ->’, a, end=’nn’) # Теперь a == 9.0, что равнозначно a = a/2. a /= 2 print(‘a /= 2 ->’, a, end=’nn’) # Теперь a == 81.0, что равнозначно a = a**2. a **= 2 print(‘a **= 2 ->’, a, end=’nn’) # Теперь a == 1.0, что равнозначно a = a%2. a %= 2 print(‘a %= 2 ->’, a)
a = 3 -> 3 a += 6 -> 9 a *= 2 -> 18 a /= 2 -> 9.0 a **= 2 -> 81.0 a %= 2 -> 1.0
Пример №2. Комбинированная форма присваивания.
Таким образом, комбинированная инструкция присваивания объединяет в себе выражение и присваивание, являясь по сути краткой формой записи кода. И хотя, например, инструкции num += 25 и num = num + 25 дадут один и тот же результат, первая из них выглядит явно компактнее. Кроме того, если объект справа относится к категории изменяемых объектов и поддерживает указанную операцию, комбинированная инструкция присваивания может выполняться даже быстрее за счет непосредственного изменения объекта вместо создания и изменения его копии (см. пример №3 ).
Код Результат pythonCodes
# Импортируем модуль time. import time # Получаем стартовое значение времени. t_1 = time.time() # Размер начнет быстро расти, что с # увеличением кол-ва итераций приведет в # данном случае к замедлению работы. li = [0] # Запускаем цикл 10 млн. раз. for i in range(0, 10**5): # Обычное присваивание. li = li + [1] # Получаем конечное значение времени. t_2 = time.time() # Вывело 1.7589106559753 сек. print(round((t_2 — t_1), 13), ‘сек’, end=’nn’) # Тоже самое, но для комбинированного присваивания. # Получаем стартовое значение времени. t_1 = time.time() # Здесь список тоже будет расти, но список будет # изменяться напрямую, а не через создание копии. li = [0] # Запускаем цикл 10 млн. раз. for i in range(0, 10**5): # Комбинированное присваивание. li += [1] # Получаем конечное значение времени. t_2 = time.time() # Вывело 1.4650475978851 сек. print(round((t_2 — t_1), 13), ‘сек’)
21.4193923473358 сек 0.0101900100708 сек
Пример №3. Преимущества комбинированной формы присваивания.
Метод time() одноименного модуля time стандартной библиотеки Python возвращает время, выраженное в секундах с начала эпохи. В операционных системах Unix , например, за начало эпохи принимается 1 января 1970 , 00 : 00 : 00 ( UTC ). Но поскольку в программах в основном используются интервалы времени между двумя событиями, а не время, прошедшее с начала эпохи, знать дату начала эпохи какой-либо конкретной операционной системы вовсе необязательно, т.к. разница между двумя временными точками для всех платформ получается совершенно одинаковой.
Давайте еще раз и в одном месте перечислим основные инструкции присваивания, комбинированные с арифметическими операторами:
- a += b – тоже самое, что и a = a + b ;
- a -= b – тоже самое, что и a = a — b ;
- a *= b – тоже самое, что и a = a * b ;
- a **= b – тоже самое, что и a = a**b ;
- a /= b – тоже самое, что и a = a / b ;
- a //= b – тоже самое, что и a = a // b ;
- a %= b – тоже самое, что и a = a % b .
Позиционное присваивание
Еще одной формой присваивания в Python является , которое связывает объекты последовательностей справа от оператора присваивания с именами, перечисляемыми слева от него. При этом присваивание выполняется слева направо согласно местоположениям имен и соответствующих им объектов (см. пример №4 ).
Код Результат pythonCodes
# Позиционное присваивание кортежа значений кортежу переменных. a, b = 3, 5 # Выведет a == 3, b == 5. print(‘a ==’, a, ‘, b ==’, b, end=’nn’) # Позиционное присваивание списка значений кортежу переменных. a, b = [3, 5] # Выведет a == 3, b == 5. print(‘a ==’, a, ‘, b ==’, b, end=’nn’) # Позиционное присваивание списка значений списку переменных. [a, b] = [3, 5] # Выведет a == 3, b == 5. print(‘a ==’, a, ‘, b ==’, b, end=’nn’) # Позиционное присваивание строки списку переменных. [a, b] = ‘AB’ # Выведет a == A, b == B. print(‘a ==’, a, ‘, b ==’, b, end=’nn’) # Кол-во присв-ых значений должно совпадать с кол-м переменных. a, b = ‘ABC’ # too many values to unpack (expected 2). print(‘a ==’, a, ‘, b ==’, b)
a == 3 , b == 5 a == 3 , b == 5 a == 3 , b == 5 a == A , b == B too many values to unpack (expected 2)
Пример №4. Позиционное присваивание (часть 1).
Как видим, данная форма присваивания позволяет смешивать последовательности разных типов. Здесь главное, чтобы количество присваиваемых значений совпадало с количеством переменных, которым эти значения будут присваиваться. Но и эта проблема может быть решена за счет имеющейся возможности использования в присваивании расширенного синтакиса распаковывания последовательностей (см. пример №5 ).
Код Результат pythonCodes
# Используем синтаксис распаковывания последовательности. a, b, *c = [1, 2, 3, 4, 5] # Выведет a == 1, b == 2, c == [3, 4, 5]. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) *a, b, c = [1, 2, 3, 4, 5] # Выведет a == [1, 2, 3], b == 4, c == 5. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) a, *b, c = [1, 2, 3, 4, 5] # Выведет a == 1, c == [2, 3, 4], b == 5. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) # Граничный случай. a, b, *c = [1, 2, 3] # Выведет a == 1, b == 2, c == [3]. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) # Еще один граничный случай. a, b, *c = [1, 2] # Выведет a == 1, b == 2, c == []. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) # Еще один граничный случай. *c, = [1, 2] # Выведет c == [1, 2]. print(‘c ==’, c, end=’nn’) # Использовать несколько звездочек запрещено. # *a, b, *c = [1, 2] # Так тоже нельзя, нужна последовательность имен. # *c = [1, 2]
a == 1 , b == 2 , c == [3, 4, 5] a == [1, 2, 3] , b == 4 , c == 5 a == 1 , b == [2, 3, 4] , c == 5 a == 1 , b == 2 , c == [3] a == 1 , b == 2 , c == [] c == [1, 2]
Пример №5. Позиционное присваивание (часть 2).
Благодаря наличию имени со звездочкой все лишние значения автоматически помещаются в соответсвующий список именно так, как и ожидается. Однако нужно не забывать, что можно использовать только одну переменную со звездочкой, а сама переменная должна принадлежать последовательности даже в том случае, если она будет одна (поставив запятую в инструкции *c, = [1, 2] мы автоматически получили кортеж и смогли избежать ошибки).
Следует добавить, что расширенная операция распаковывания последовательностей может использоваться не только в случаях явного присваивания значений, но также и в заголовках циклов, вызовах функций и других операциях неявного присваивания значений.
Групповое присваивание одного значения
В случае группового присваивания объект, расположенный справа, присваивается всем переменным группы (см. пример №6 ). В результате несколько отдельных инструкций присваивания могут быть заменены одной эквивалентной и более компактной инструкцией.
Код Результат pythonCodes
# Используем 3 инструкции присваивания по отдельности. a = ‘Ok’ b = a c = b # Выведет a == ‘Ok’, b == ‘Ok’, c == ‘Ok’. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) # Или 1 эквивалентную инст-цию группового присваивания. c = b = a = ‘Ok’ # Опять же выведет a == ‘Ok’, b == ‘Ok’, c == ‘Ok’. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c)
a == Ok , b == Ok , c == Ok a == Ok , b == Ok , c == Ok
Пример №6. Присваивание одного значения группе переменных (часть 1).
Следует иметь в виду, что при групповом присваивании в памяти создается всего лишь один объект, разделяемый всеми переменными группы. Поэтому такая форма присваивания будет полезна для неизменяемых объектов, например, чисел или строк. А вот при использовании изменяемых объектов типа списков или словарей нужно быть осторожными, т.к. изменение объекта через одну из переменных группы будет оказывать влияние и на другие переменные (см. пример №7 ). Это связано с тем, что переменные в Python хранят не сами объекты, а ссылки на них. А раз так, то даже после изменения объекта через одну из ссылок все остальные по-прежнему будут указывать на тот же, пусть и модифицированный, объект.
Код Результат pythonCodes
# Используем число (неизменяемый объект). c = b = a = 0 # Изменим b и c. b = 1 c = 2 # Выведет a == 0, b == 1, c == 2. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) # Используем список (изменяемый объект). c = b = a = [] # Пробуем изменить b и c. b += [1] c += [2] # Выведет для всех [1, 2]. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c)
a == 0 , b == 1 , c == 2 a == [1, 2] , b == [1, 2] , c == [1, 2]
Пример №7. Присваивание одного значения группе переменных (часть 2).
Таким образом, во избежание проблем с изменяемыми объектами, их инициализацию лучше производить в отдельных инструкциях, как было показано в первой части примера №6 .
Выражения присваивания в Python
Все рассмотренные нами формы присваивания относятся к инструкциям. Но их запрещено использовать в выражениях, что иногда может быть весьма полезным. Поэтому начиная с версии Python 3.8 было решено ввести новую конструкцию NAME := expr с возможностью использования в выражениях (см. пример №8 ). Конструкция получила название или же , а оператор := стал неофициально называться .
Код Результат pythonCodes
# В выражении инициализируются сразу 3 переменные. a = (b := 3) + (c := 5) # Выведет a == 8, b == 3, c == 5. print(‘a ==’, a, ‘, b ==’, b, ‘, c ==’, c, end=’nn’) # Список функций (для однозначности используем скобки). li = [(x_2 := lambda y: y**2), (x_3 := lambda y: y**3)] # Выведет li[0](5) == 25, li[1](5) == 125. print(‘li[0](5) ==’, li[0](5), ‘, li[1](5) ==’, li[1](5)) # Выведет те же результаты: x_2(5) == 25, x_3(5) == 125. print(‘x_2(5) ==’, x_2(5), ‘, x_3(5) ==’, x_3(5), end=’nn’)
a == 8 , b == 3 , c == 5 li[0](5) == 25 , li[1](5) == 125 x_2(5) == 25 , x_3(5) == 125
Пример №8. Использование выражений присваивания (часть 1).
Использовать выражение присваивания в коде верхнего уровня без скобок запрещается. Например, инструкция x = y := 5 не пройдет, нужно использовать скобки: x = (y := 5) . И вообще, использование скобок с моржовым оператором следует сразу же взять на вооружение, т.к. это поможет избежать многих досадных ошибок.
Возможно, кто-то сочтет такое нововведение нецелесообразным, ведь выражения порой и так бывают довольно громоздкими, чтобы вводить туда еще и дополнительные конструкции с набором ограничений. Но ситуации бывают разные как, например, в примере №9 .
Код Результат pythonCodes
# Выводим сообщение и призыв к вводу. print(‘Введите 2 положительных числа.’) x = float(input(‘Введите 1-е число: ‘)) y = float(input(‘Введите 2-е число: ‘)) # Для уменьшения объема кода. mess = ‘Разрешены только положительные числа!’ # Осуществляем проверки и вывод результатов. if y > 0: res = x/y if res > 0: print(‘x/y =’, res) else: print(mess, end=’nn’) else: print(mess, end=’nn’) # Выводим сообщение и призыв к вводу. print(‘Введите 2 положительных числа.’) x = float(input(‘Введите 1-е число: ‘)) y = float(input(‘Введите 2-е число: ‘)) # Проверка в одном if. if y > 0 and (res := x/y) > 0: # Выводим результат. print(‘x/y =’, res) # Иначе сообщение об ошибке. else: print(‘Разрешены только положительные числа!’)
Введите 2 положительных числа.
Введите 1-е число: 5 Введите 2-е число: 10 x/y = 0.5 Введите 2 положительных числа. Введите 1-е число: 5 Введите 2-е число: 10 x/y = 0.5
Пример №9. Использование выражений присваивания (часть 2).
Подробнее о выражениях присваивания можете почитать на официальном сайте в документации к PEP 572 – Assignment Expressions.
Краткие итоги параграфа
- В Python инструкции присваивания всегда сохраняют ссылки на объекты, например, в переменных или в элементах структур данных, и никогда не создают копии присваиваемых объектов.
- Классическая форма присваивания имеет вид NAME = expr , что соответствует синтаксису многих других языков программирования. Однако в Python доступны и другие формы инструкций присваивания: комбинированные инструкции присваивания (например, y **= 3 ), позиционное присваивание (например, x, y = [3, 5] или x, *y = ‘abcdef’ ), а также групповое присваивание одного значения (например, a = b = c = 33 ).
- При групповом присваивании одного значения в памяти создается всего лишь один объект, разделяемый всеми переменными группы. Поэтому такая форма присваивания будет полезна для неизменяемых объектов, например, чисел или строк. А вот при использовании изменяемых объектов типа списков или словарей нужно быть осторожными, т.к. изменение объекта через одну из переменных группы будет оказывать влияние и на другие переменные.
- Поскольку в Python запрещается использовать инструкции в выражениях, начиная с версии 3.8 была введена специальная конструкция NAME := expr , получившая название выражения присваивания и предназначенная для присваивания значений внутри выражений, например, a = (b := 3) + (c := 5) .
Вопросы и задания для самоконтроля
1. Перечислите основные формы инструкций присваивания в Python . Показать решение.
Ответ. Классическая форма NAME = expr , комбинированные инструкции присваивания NAME operator= expr , позиционное присваивание NAME_1, . NAME_n = expr_1, . expr_n , а также групповое присваивание одного значения NAME_1 = . = NAME_n = expr .
2. Имеются две инициализированные переменные a = ‘one’ и b = ‘two’ . Поменяйте значения переменных местами, использовав позиционную форму инструкции присваивания. Показать решение.
Ответ. Так как в процессе позиционного присваивания интерпретатор создает временный кортеж, где сохраняются оригинальные значения переменных справа, данная форма присваивания может использоваться для реализации обмена значений переменных без создания временной переменной. Таким образом, кортеж справа автоматически запоминает предыдущие значения переменных.
Решение Результат pythonCodes
# Инициализируем переменные. a = ‘one’ b = ‘two’ # Производим замену значений. a, b = ‘two’, ‘one’ print(‘a == ‘, a, ‘, b == ‘, b, sep=»)
a == two, b == one
3. О чем следует помнить, когда трем переменным присваивается один и тот же изменяемый объект? Показать решение.
Ответ. Если, например, выполнить присваивание следующим образом: a = b = c = [] , то все три переменные будут ссылаться на один и тот же объект. Поэтому непосредственное изменение объекта с помощью одной переменной (например, A.append(5) ) отразится и на других. Однако это справедливо только для изменений, производимых непосредственно в изменяемых объектах, таких как списки или словари. Для неизменяемых объектов, вроде чисел и строк, такой проблемы не возникает.
4. Какие из представленных фрагментов кода содержат ошибки: a, b = [3, ‘3’] ; x, *y = 1, 2, 3 ; *x, = 1, 2, 3 ; *x, y, *z = 1, 2, 3, 4 ? Объясните ответ. Показать решение.
Ответ. Все фрагменты кода, кроме последнего, верны. А вот последняя инструкция содержит две переменные со звездочкой, что расширенным синтаксисом распаковывания последовательностей не допускается.
Быстрый переход к другим страницам
- Инструкции, выражения и операторы в Python
- Инструкции присваивания в Python
- Условная инструкция if в Python
- Вернуться к оглавлению учебника
Источник: okpython.net