Параметры и аргументы функции

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

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

Рассмотрим схему и поясняющий ее пример:

Параметры и аргументы функции. Схема и пример

Когда функция вызывается, то ей передаются аргументы. В примере указаны глобальные переменные num1 и num2. Однако на самом деле передаются не эти переменные, а их значения. В данном случае числа 100 и 12. Другими словами, мы могли бы писать mathem(100, 12). Разницы не было бы.

Когда интерпретатор переходит к функции, чтобы начать ее исполнение, он присваивает переменным-параметрам переданные в функцию значения-аргументы. В примере переменной a будет присвоено 100, b будет присвоено 12.

Изменение значений a и b в теле функции никак не скажется на значениях переменных num1 и num2. Они останутся прежними. В Python такое поведение характерно для неизменяемых типов данных, к которым относятся, например, числа и строки. Говорят, что в функцию данные передаются по значению. Так, когда a присваивалось число 100, то это было уже другое число, не то, на которое ссылается переменная num1. Число 100 было скопировано и помещено в отдельную ячейку памяти для переменной a.

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

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

Произвольное количество аргументов

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

Однако в Python у функций бывают параметры, которым уже присвоено значение по-умолчанию. В таком случае, при вызове можно не передавать соответствующие этим параметрам аргументы. Хотя можно и передать. Тогда значение по умолчанию заменится на переданное.

def cylinder(h, r = 1):
    side = 2 * 3.14 * r * h
    circle = 3.14 * r**2
    full = side + 2 * circle
    return full
 
figure1 = cylinder(4, 3)
figure2 = cylinder(5)
print(figure1)
print(figure2)

Вывод:

131.88
37.68

При втором вызове cylinder() мы указываем только один аргумент. Он будет присвоен переменной-параметру h. Переменная r будет равна 1.

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

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

… 
figure3 = cylinder(10, 2)
figure4 = cylinder(r=2, h=10)
print(figure3)
print(figure4)

В данном случае оба вызова – это вызовы с одними и теми же аргументами-значениями. Просто в первом случае сопоставление параметрам-переменным идет в порядке следования. Во-втором случае – по ключам, которыми выступают имена параметров.

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

def oneOrMany(*a):
    print(a)
 
oneOrMany(1)
oneOrMany('1',1, 2, 'abc')
oneOrMany()

Результат:

(1,)
('1', 1, 2, 'abc')
()

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

Практическая работа

Напишите программу, в которой определены следующие четыре функции:

  1. Функция getInput() не имеет параметров, запрашивает ввод с клавиатуры и возвращает в основную программу полученную строку.

  2. Функция testInput() имеет один параметр. В теле она проверяет, можно ли переданное ей значение преобразовать к целому числу. Если можно, возвращает логическое True. Если нельзя – False.

  3. Функция strToInt() имеет один параметр. В теле преобразовывает переданное значение к целочисленному типу. Возвращает полученное число.

  4. Функция printInt() имеет один параметр. Она выводит переданное значение на экран и ничего не возвращает.

В основной ветке программы вызовите первую функцию. То, что она вернула, передайте во вторую функцию. Если вторая функция вернула True, то те же данные (из первой функции) передайте в третью функцию, а возвращенное третьей функцией значение – в четвертую.

Примеры решения в android-приложении и pdf-версии курса.

Создано

Обновлено

Комментарии

Добрый вечер!
Задача стоит в том, что бы сделать "Глубокое копирование списков". Если у нас есть список в списке, мы должны не только копировать внешний список, но и тот, который внутри. Дабы при изменении праобраза копии, не менялись внутренние списки самой копии. Ну в общем, надеюсь поймете о чем я хотел сказать и в чем я ошибся. Мне кажется проблема с возвращением значения в функцию.
вот:

def copy(a,b):
	a = b.copy()
	i = 1
	for q in b:
		if type(q) == list:
			return copy(a[i], b[i])
	i += 1
	return a

Как-то так.