Параметры и аргументы функций в Python
Обновлено:
1. Передача данных в функцию
Ранее мы создавали функции, которые не получали никаких данных:
def get_greeting():
return 'Hello'
Такая функция при каждом вызове возвращает один и тот же результат:
print(get_greeting())
print(get_greeting())
Результат:
Hello
Hello
Чтобы одна функция могла работать с разными значениями, ей нужно передавать данные.
Передаваемые данные называются аргументами.
2. Параметр и аргумент
Важно различать два термина:
- параметр;
- аргумент.
Рассмотрим определение функции:
def calculate_square_area(side_length):
return side_length ** 2
Имя:
side_length
в определении функции называется параметром.
Теперь вызовем функцию:
calculate_square_area(5)
Число:
5
называется аргументом.
Кратко:
Параметр указывается при определении функции.
Аргумент передаётся при вызове функции.
В официальной документации имена внутри скобок определения функции называются формальными параметрами, а передаваемые при вызове значения — аргументами.
3. Первый параметр функции
Создадим функцию для нахождения площади квадрата:
def calculate_square_area(side_length):
return side_length ** 2
Функция должна получить длину одной стороны квадрата.
Полученное значение будет доступно внутри функции под именем:
side_length
После этого функция возведёт длину стороны во вторую степень и вернёт площадь.
4. Вызов функции с одним аргументом
result = calculate_square_area(5)
print(result)
Результат:
25
При вызове:
calculate_square_area(5)
число 5 передаётся в функцию.
Внутри функции параметр:
side_length
начинает ссылаться на объект 5.
Функция выполняет:
5 ** 2
и возвращает:
25
5. Как аргумент попадает в параметр
Определение функции:
def calculate_square_area(side_length):
return side_length ** 2
Вызов:
calculate_square_area(5)
Упрощённо работу можно представить так:
Аргумент:
5
передаётся в параметр:
side_length
Во время вызова:
side_length ─────> 5
После этого тело функции использует имя side_length.
6. Одна функция и разные аргументы
print(calculate_square_area(5))
print(calculate_square_area(6))
print(calculate_square_area(9))
Результат:
25
36
81
Мы написали алгоритм только один раз:
side_length ** 2
Но использовали его для разных значений.
7. Переиспользование функции
Без функции пришлось бы несколько раз писать:
5 ** 2
6 ** 2
9 ** 2
С функцией мы используем понятное имя:
calculate_square_area(5)
calculate_square_area(6)
calculate_square_area(9)
Имя функции сразу сообщает, что программа рассчитывает площадь квадрата.
8. Обязательный параметр
Параметр:
side_length
является обязательным.
Это означает, что при вызове функции нужно передать значение для этого параметра.
Правильно:
calculate_square_area(5)
Неправильно:
calculate_square_area()
Во втором варианте функция не получила длину стороны.
Будет ошибка:
TypeError
9. Вызов без обязательного аргумента
def calculate_square_area(side_length):
return side_length ** 2
calculate_square_area()
Python сообщает, что не было передано обязательное значение для параметра:
side_length
Функция не может выполнить:
side_length ** 2
потому что значение side_length отсутствует.
10. Сравнение с функцией len()
Функция len() тоже ожидает один обязательный аргумент.
Правильно:
len('Python')
Неправильно:
len()
Вызов без аргумента приведёт к ошибке TypeError.
Наша функция работает похожим образом:
calculate_square_area(5)
Правильно.
calculate_square_area()
Ошибка.
11. Слишком много аргументов
Функция определена с одним параметром:
def calculate_square_area(side_length):
return side_length ** 2
Поэтому в наших примерах она ожидает ровно один аргумент.
Неправильно:
calculate_square_area(5, 10)
Переданы два значения, но функция подготовила только один параметр.
Будет ошибка:
TypeError
12. Позиционная передача аргумента
На этом уроке передаём аргументы по позиции:
calculate_square_area(5)
Первый переданный аргумент попадает в первый параметр функции.
В определении есть один параметр:
def calculate_square_area(side_length):
В вызове есть один аргумент:
calculate_square_area(5)
Поэтому число 5 попадает в side_length.
Другие способы передачи аргументов будут изучаться позже.
13. Какие объекты принимает функция
Внутри функции используется оператор:
**
def calculate_square_area(side_length):
return side_length ** 2
На данном этапе в эту функцию передаём:
int;float.
Пример с целым числом:
calculate_square_area(5)
Результат:
25
Пример с вещественным числом:
calculate_square_area(2.5)
Результат:
6.25
14. Ошибка при неподходящем типе
Передадим строку:
calculate_square_area('5')
Внутри функции Python попытается выполнить:
'5' ** 2
Строка не поддерживает такую операцию.
Будет ошибка:
TypeError
Причина ошибки находится не в самом механизме передачи аргумента.
Аргумент успешно попал в функцию, но операция внутри функции не умеет работать с полученным объектом.
15. Функция пока не проверяет тип
Наша функция записана так:
def calculate_square_area(side_length):
return side_length ** 2
В ней нет специальных проверок.
Python не запрещает передать строку заранее.
Ошибка появляется только тогда, когда выполняется неподдерживаемая операция:
side_length ** 2
В будущем мы познакомимся с:
- аннотациями типов;
- документацией функций;
- проверками полученных данных;
- обработкой ошибок.
Сейчас определяем ожидаемые типы по операциям внутри функции.
16. Результат функции можно сохранить
first_area = calculate_square_area(5)
second_area = calculate_square_area(8)
print(first_area)
print(second_area)
Результат:
25
64
Каждый вызов возвращает отдельный результат.
17. Результат можно сразу передать в print()
Необязательно сначала создавать переменную:
print(calculate_square_area(6))
Сначала вызывается:
calculate_square_area(6)
Функция возвращает:
36
После этого внешний print() выводит результат:
36
18. Вложенный вызов функции
Результат одного вызова можно передать в следующий вызов:
print(calculate_square_area(calculate_square_area(5)))
Сначала выполняется внутренняя функция:
calculate_square_area(5)
Результат:
25
После этого получается:
calculate_square_area(25)
Результат:
625
Именно это число выводит print().
19. Порядок выполнения вложенного вызова
calculate_square_area(calculate_square_area(5))
Первый шаг:
calculate_square_area(5)
Результат:
25
Второй шаг:
calculate_square_area(25)
Результат:
625
Функции внутри скобок выполняются раньше внешней функции.
20. Функция с двумя параметрами
Создадим функцию сложения двух чисел:
def add_numbers(first_number, second_number):
return first_number + second_number
В определении находятся два параметра:
first_number
second_number
При вызове нужно передать два аргумента.
21. Вызов функции с двумя аргументами
result = add_numbers(10, 5)
print(result)
Результат:
15
Первый аргумент:
10
попадает в первый параметр:
first_number
Второй аргумент:
5
попадает во второй параметр:
second_number
22. Позиции аргументов
add_numbers(10, 5)
Упрощённая схема:
10 ─────> first_number
5 ─────> second_number
Затем функция выполняет:
first_number + second_number
То есть:
10 + 5
23. Разные вызовы add_numbers()
print(add_numbers(10, 5))
print(add_numbers(2, 3))
print(add_numbers(100, 250))
Результат:
15
5
350
Алгоритм внутри функции не меняется.
Меняются только передаваемые аргументы.
24. Недостаточно аргументов
Функция ожидает два обязательных значения:
def add_numbers(first_number, second_number):
return first_number + second_number
Неправильно:
add_numbers(10)
Значение для first_number передано.
Значение для second_number отсутствует.
Будет ошибка:
TypeError
25. Слишком много аргументов
Неправильно:
add_numbers(10, 5, 3)
Функция подготовила два параметра:
first_number
second_number
Но получила три аргумента.
Будет ошибка:
TypeError
26. Аргументы являются обязательными
В нашей функции:
def add_numbers(first_number, second_number):
return first_number + second_number
оба параметра являются обязательными.
Для успешного вызова передаём ровно два аргумента:
add_numbers(10, 5)
Значения по умолчанию на этом уроке не рассматриваются.
27. Позиция особенно важна для разных действий
При сложении перестановка чисел не изменит результат:
add_numbers(10, 5)
и:
add_numbers(5, 10)
оба вызова вернут:
15
Но это особенность сложения.
Рассмотрим вычитание:
def subtract_numbers(first_number, second_number):
return first_number - second_number
28. Позиции в функции вычитания
subtract_numbers(10, 5)
Результат:
5
Но:
subtract_numbers(5, 10)
Результат:
-5
Первый аргумент всегда попадает в первый параметр, а второй — во второй.
Поэтому порядок позиционных аргументов имеет значение.
29. Ожидаемые типы для add_numbers()
Внутри функции используется оператор:
+
def add_numbers(first_number, second_number):
return first_number + second_number
Для числового сложения передаём int и float:
add_numbers(10, 5)
add_numbers(2.5, 3.5)
add_numbers(10, 2.5)
30. Операция определяет поведение функции
Python смотрит не на название функции, а на операции внутри неё.
Например:
add_numbers('Py', 'thon')
технически вернёт:
'Python'
Потому что оператор + умеет соединять две строки.
Но по смыслу наша функция предназначена для сложения чисел.
Поэтому передаём в неё числовые объекты.
31. Несовместимые типы
add_numbers(10, '5')
Внутри функции получится:
10 + '5'
Число нельзя сложить со строкой.
Будет ошибка:
TypeError
Даже собственная функция может завершиться с ошибкой, если переданные объекты не поддерживают действия из её тела.
32. Использование результата нескольких функций
value = add_numbers(7, 3) * add_numbers(2, 3)
print(value)
Сначала:
add_numbers(7, 3)
возвращает:
10
После этого:
add_numbers(2, 3)
возвращает:
5
Остаётся:
10 * 5
Результат:
50
33. Параметры находятся в локальной области
Создадим функцию:
def show_local_names(first_name):
local_number = 1
print('local:', dir())
Вызовем её:
show_local_names('John')
Среди локальных имён будут:
first_name
local_number
Параметр функции является локальным именем.
34. Что происходит при вызове
show_local_names('John')
Строка:
'John'
передаётся в параметр:
first_name
Во время вызова внутри локальной области появляется связь:
first_name ─────> 'John'
Затем функция создаёт ещё одно локальное имя:
local_number ─────> 1
35. Параметр похож на локальную переменную
Параметр:
first_name
можно использовать внутри функции так же, как обычное локальное имя:
def show_user_name(first_name):
print(first_name)
Вызов:
show_user_name('John')
Результат:
John
36. Параметры не появляются в глобальной области
def show_user_name(first_name):
print(first_name)
Имя:
first_name
относится к локальной области функции.
После завершения вызова нельзя обратиться к нему в глобальной области:
print(first_name)
Будет ошибка:
NameError
37. Параметр создаётся при каждом вызове
def show_user_name(first_name):
print(first_name)
Первый вызов:
show_user_name('John')
Во время него локальный параметр ссылается на строку 'John'.
Второй вызов:
show_user_name('Anna')
Во время нового вызова создаётся новая локальная область, и параметр ссылается на строку 'Anna'.
38. У каждого вызова своя локальная область
show_user_name('John')
show_user_name('Anna')
Первый вызов и второй вызов не используют одну общую локальную переменную.
Для каждого вызова создаётся собственная локальная область.
После завершения вызова обычные локальные связи освобождаются.
39. Несколько параметров в локальной области
def show_user_data(first_name, age):
local_message = 'User data'
print('local:', dir())
Вызов:
show_user_data('John', 25)
Среди локальных имён будут:
age
first_name
local_message
В локальную область попадают:
- параметры;
- переменные, созданные в теле функции.
40. Глобальная область не получает параметры
global_message = 'Program started'
def show_user_data(first_name, age):
local_message = 'User data'
print('local:', dir())
show_user_data('John', 25)
print('global:', dir())
Среди глобальных имён будут:
global_message
show_user_data
Параметры:
first_name
age
и локальная переменная:
local_message
не становятся глобальными.
41. Функция с тремя параметрами
Функция может принимать больше двух аргументов:
def add_three_numbers(
first_number,
second_number,
third_number,
):
return first_number + second_number + third_number
Здесь находятся три обязательных параметра.
42. Вызов с тремя аргументами
result = add_three_numbers(5, 2, 10)
print(result)
Результат:
17
Соответствие по позициям:
5 ─────> first_number
2 ─────> second_number
10 ─────> third_number
43. Другой вызов той же функции
print(add_three_numbers(8, 5, 1))
Результат:
14
Мы снова используем тот же алгоритм, но передаём другие значения.
44. Нужно передать точное количество аргументов
Функция определена с тремя обязательными параметрами:
def add_three_numbers(
first_number,
second_number,
third_number,
):
return first_number + second_number + third_number
Правильно:
add_three_numbers(5, 2, 10)
Неправильно:
add_three_numbers(5, 2)
Неправильно:
add_three_numbers(5, 2, 10, 20)
Оба неправильных вызова приведут к TypeError.
45. Перенос длинного списка параметров
Если определение функции не помещается в одну короткую строку, параметры можно перенести:
def add_three_numbers(
first_number,
second_number,
third_number,
):
return first_number + second_number + third_number
Каждый параметр записан на отдельной строке.
После последнего параметра поставлена запятая.
Такой вариант удобно читать.
Для короткой функции допустима одна строка:
def add_three_numbers(first_number, second_number, third_number):
return first_number + second_number + third_number
46. Развёрнутая запись функции
Создадим функцию, которая возвращает минимальное и максимальное числа:
def get_minimum_and_maximum(numbers):
minimum_number = min(numbers)
maximum_number = max(numbers)
result = (minimum_number, maximum_number)
return result
Здесь каждое действие записано отдельно.
47. Как работает развёрнутая функция
def get_minimum_and_maximum(numbers):
minimum_number = min(numbers)
maximum_number = max(numbers)
result = (minimum_number, maximum_number)
return result
Порядок работы:
- функция получает итерируемый объект;
- находит минимальное число;
- находит максимальное число;
- создаёт кортеж;
- возвращает кортеж.
48. Вызов развёрнутой функции
result = get_minimum_and_maximum([7, 10, 2, 5, 3])
print(result)
Результат:
(2, 10)
Первый элемент кортежа — минимальное значение.
Второй элемент — максимальное значение.
49. Распаковка результата
Функция возвращает кортеж с двумя элементами:
(2, 10)
Его можно распаковать:
minimum_number, maximum_number = get_minimum_and_maximum(
[7, 10, 2, 5, 3]
)
print(minimum_number)
print(maximum_number)
Результат:
2
10
50. Работа со списком и кортежем
print(get_minimum_and_maximum([7, 10, 2, 5, 3]))
Результат:
(2, 10)
print(get_minimum_and_maximum((34, 142, 86)))
Результат:
(34, 142)
Функция работает с изученными итерируемыми объектами, элементы которых можно сравнить с помощью min() и max().
51. Сокращённая запись функции
Ту же функцию можно записать короче:
def get_minimum_and_maximum(numbers):
return (min(numbers), max(numbers))
Результат будет таким же.
52. Сравнение двух вариантов
Развёрнутый вариант:
def get_minimum_and_maximum(numbers):
minimum_number = min(numbers)
maximum_number = max(numbers)
result = (minimum_number, maximum_number)
return result
Короткий вариант:
def get_minimum_and_maximum(numbers):
return (min(numbers), max(numbers))
Оба варианта правильные.
53. Когда полезен развёрнутый вариант
Развёрнутая запись удобна, когда:
- алгоритм только изучается;
- нужно видеть каждый этап;
- промежуточные значения имеют важный смысл;
- результаты будут использоваться несколько раз;
- отдельные имена делают код понятнее.
Пример:
minimum_number = min(numbers)
maximum_number = max(numbers)
По именам сразу понятно, что находится в переменных.
54. Когда полезен короткий вариант
Короткая запись подходит, когда:
- выражение небольшое;
- оно легко читается;
- промежуточные значения используются один раз;
- дополнительные переменные не улучшают понимание.
Пример:
return (min(numbers), max(numbers))
Запись остаётся понятной и не содержит лишних имён.
55. Не нужно создавать переменную для каждого действия
Такой код допустим:
def calculate_square_area(side_length):
result = side_length ** 2
return result
Но переменная result используется только один раз.
Поэтому можно написать:
def calculate_square_area(side_length):
return side_length ** 2
Второй вариант короче и остаётся понятным.
56. Когда промежуточную переменную стоит создать
Предположим, результат используется несколько раз:
def calculate_numbers_total(numbers):
total = sum(numbers)
print('Calculated total:', total)
return total
Переменная total нужна и для print(), и для return.
В таком случае нет смысла дважды вызывать:
sum(numbers)
57. Повторное вычисление без переменной
Менее удачный вариант:
def calculate_numbers_total(numbers):
print('Calculated total:', sum(numbers))
return sum(numbers)
Функция два раза выполняет один и тот же расчёт.
Лучше вычислить результат один раз:
def calculate_numbers_total(numbers):
total = sum(numbers)
print('Calculated total:', total)
return total
58. Читаемость важнее минимального количества строк
Самый короткий код не всегда является самым хорошим.
Главная задача — написать код, который:
- правильно работает;
- легко читается;
- понятно называет данные;
- не повторяет лишние вычисления;
- удобно изменяется.
Иногда промежуточная переменная улучшает код.
Иногда она только создаёт лишнее имя.
59. Функция является объектом
Когда Python выполняет:
def calculate_square_area(side_length):
return side_length ** 2
в оперативной памяти появляется объект функции.
Имя:
calculate_square_area
связывается с этим объектом:
calculate_square_area ─────> объект функции
Имя функции является такой же ссылкой на объект, как и другие имена в Python.
60. Передача функции без вызова
Рассмотрим:
function_copy = calculate_square_area
Круглых скобок нет.
Поэтому функция не вызывается.
Имя function_copy начинает ссылаться на тот же объект функции:
calculate_square_area ──┐
├────> объект функции
function_copy ──────────┘
61. Вызов функции через второе имя
function_copy = calculate_square_area
print(function_copy(5))
Результат:
25
Имя function_copy ссылается на тот же объект функции.
Поэтому через него тоже можно выполнить вызов.
62. Копирование ссылки и вызов — разные действия
Копирование ссылки:
function_copy = calculate_square_area
Вызов функции и сохранение результата:
result = calculate_square_area(5)
В первом случае в function_copy находится объект функции.
Во втором случае в result находится число:
25
63. Функция sys.getrefcount()
Для исследования количества ссылок можно использовать:
from sys import getrefcount
Создадим функцию:
def calculate_square_area(side_length):
return side_length ** 2
Проверим счётчик:
print(getrefcount(calculate_square_area))
В CPython часто будет показано:
2
Одна ссылка связана с глобальным именем функции.
Ещё одна временная ссылка появляется при передаче объекта в саму функцию getrefcount(). Точное число может зависеть от версии Python и среды запуска, поэтому для основной логики программы на него полагаться нельзя.
64. Дополнительная ссылка на функцию
from sys import getrefcount
def calculate_square_area(side_length):
return side_length ** 2
print(getrefcount(calculate_square_area))
function_copy = calculate_square_area
print(getrefcount(calculate_square_area))
Типичный результат:
2
3
После строки:
function_copy = calculate_square_area
появилась дополнительная ссылка на объект функции.
65. Удаление первоначального имени
del calculate_square_area
Первоначальное имя удалено.
Но объект функции продолжает существовать, потому что остаётся другая ссылка:
function_copy
Функцию всё ещё можно вызвать:
print(function_copy(5))
Результат:
25
66. Имя удалено, но объект остался
После:
del calculate_square_area
такой вызов больше не работает:
calculate_square_area(5)
Будет ошибка:
NameError
Но:
function_copy(5)
продолжает работать.
Удалено только имя calculate_square_area, а не сам объект функции.
67. Полный пример со ссылками на функцию
from sys import getrefcount
def calculate_square_area(side_length):
return side_length ** 2
print(getrefcount(calculate_square_area))
function_copy = calculate_square_area
print(getrefcount(calculate_square_area))
del calculate_square_area
print(getrefcount(function_copy))
print(function_copy(5))
Типичный результат:
2
3
2
25
Точные значения счётчика могут отличаться.
Для нас важен общий принцип:
- новое имя увеличивает количество ссылок;
- удаление имени уменьшает количество ссылок;
- объект существует, пока на него остаются ссылки.
68. Нужно ли копировать имя функции
Технически это возможно:
function_copy = calculate_square_area
Но в обычном коде без причины так делать не нужно.
У функции уже есть понятное имя:
calculate_square_area
Именно его следует использовать на протяжении программы.
Создание дополнительных случайных имён:
- усложняет чтение;
- может запутать других разработчиков;
- затрудняет поиск функции;
- не даёт практической пользы в простом коде.
69. Не нужно перезаписывать имя функции
Неправильная практика:
def calculate_square_area(side_length):
return side_length ** 2
calculate_square_area = 10
После перезаписи имя больше не ссылается на функцию.
Вызов:
calculate_square_area(5)
приведёт к ошибке:
TypeError
Имя функции желательно сохранять неизменным.
70. Дублирование кода без функции
Предположим, в программе несколько раз рассчитывается периметр прямоугольника.
Без функции код может выглядеть так:
first_length = 5
first_width = 3
first_perimeter = (first_length + first_width) * 2
print('First perimeter:', first_perimeter)
second_length = 10
second_width = 4
second_perimeter = (second_length + second_width) * 2
print('Second perimeter:', second_perimeter)
third_length = 7.5
third_width = 2.5
third_perimeter = (third_length + third_width) * 2
print('Third perimeter:', third_perimeter)
fourth_length = 12
fourth_width = 8
fourth_perimeter = (fourth_length + fourth_width) * 2
print('Fourth perimeter:', fourth_perimeter)
Формула повторяется четыре раза:
(length + width) * 2
71. Недостатки повторяющегося кода
В предыдущем примере:
- одна формула записана несколько раз;
- файл стал длиннее;
- увеличилась вероятность опечатки;
- при изменении алгоритма придётся исправлять несколько мест;
- отдельные расчёты сложнее проверять.
Например, в одной копии можно случайно написать:
length + width * 2
и получить неправильный результат.
72. Выносим алгоритм в функцию
Создадим функцию:
def calculate_rectangle_perimeter(length, width):
return (length + width) * 2
Теперь формула находится только в одном месте.
73. Использование функции
def calculate_rectangle_perimeter(length, width):
return (length + width) * 2
first_perimeter = calculate_rectangle_perimeter(5, 3)
second_perimeter = calculate_rectangle_perimeter(10, 4)
third_perimeter = calculate_rectangle_perimeter(7.5, 2.5)
fourth_perimeter = calculate_rectangle_perimeter(12, 8)
print('First perimeter:', first_perimeter)
print('Second perimeter:', second_perimeter)
print('Third perimeter:', third_perimeter)
print('Fourth perimeter:', fourth_perimeter)
Формула написана один раз, а функция вызвана четыре раза.
74. Результаты программы
First perimeter: 16
Second perimeter: 28
Third perimeter: 20.0
Fourth perimeter: 40
Одна функция работает и с int, и с float, потому что использованные математические операторы поддерживают оба типа.
75. Сравнение двух подходов
Без функции:
first_perimeter = (first_length + first_width) * 2
second_perimeter = (second_length + second_width) * 2
third_perimeter = (third_length + third_width) * 2
fourth_perimeter = (fourth_length + fourth_width) * 2
С функцией:
def calculate_rectangle_perimeter(length, width):
return (length + width) * 2
Дальше используются только вызовы:
calculate_rectangle_perimeter(5, 3)
calculate_rectangle_perimeter(10, 4)
calculate_rectangle_perimeter(7.5, 2.5)
calculate_rectangle_perimeter(12, 8)
76. Исправление алгоритма в одном месте
Предположим, в формуле функции была ошибка.
Без функции пришлось бы исправлять каждую копию формулы.
С функцией достаточно исправить одно место:
def calculate_rectangle_perimeter(length, width):
return (length + width) * 2
Все вызовы автоматически начнут использовать исправленный алгоритм.
77. Понятное имя заменяет объяснение
Сравним:
result = (5 + 3) * 2
По этой строке нужно самостоятельно догадаться, что именно рассчитывается.
С функцией:
result = calculate_rectangle_perimeter(5, 3)
Название сразу объясняет назначение вычисления.
78. Принцип DRY
Один из известных принципов разработки называется:
DRY
Расшифровка:
Don't Repeat Yourself
Перевод:
Не повторяйся
Смысл принципа:
Одинаковая логика не должна без необходимости копироваться в разных местах программы.
79. Функции помогают соблюдать DRY
Если один алгоритм нужен несколько раз, его можно поместить в функцию:
def calculate_rectangle_perimeter(length, width):
return (length + width) * 2
После этого в программе вызывается готовая функция:
calculate_rectangle_perimeter(5, 3)
calculate_rectangle_perimeter(10, 4)
Алгоритм существует в одном месте.
80. DRY не означает объединять всё подряд
Принцип DRY не означает, что любой похожий код обязательно нужно немедленно превращать в одну функцию.
Функция должна представлять понятную самостоятельную задачу.
Хороший пример:
calculate_rectangle_perimeter()
Функция выполняет одну понятную операцию.
Плохая функция может объединять несколько несвязанных действий только ради уменьшения количества строк.
81. Основные термины урока
Параметр
Имя в определении функции:
def calculate_square_area(side_length):
side_length — параметр.
Аргумент
Значение при вызове:
calculate_square_area(5)
5 — аргумент.
Обязательный параметр
Параметр, для которого при вызове нужно передать значение.
Позиционный аргумент
Аргумент, который передаётся на определённой позиции:
add_numbers(10, 5)
82. Что изучено в трёх частях темы
В первой части мы познакомились с:
- объектом
None; - возвращаемыми значениями;
- назначением функций;
- устранением дублирования.
Во второй части мы изучили:
- ключевое слово
def; - тело функции;
- отступы;
pass;- вызов функции;
return;- локальную область;
- отличие
print()отreturn.
В третьей части мы изучили:
- параметры;
- аргументы;
- позиционную передачу;
- обязательные параметры;
- функции с одним, двумя и тремя параметрами;
- локальные параметры;
- ожидаемые типы данных;
- функции как объекты;
- ссылки на функции;
- принцип DRY.
83. Что пока не рассматриваем
На этом этапе не изучаем:
- передачу аргументов по имени;
- значения параметров по умолчанию;
- произвольное количество аргументов;
- аннотации типов;
- строки документации;
- вложенные функции;
- рекурсию;
- декораторы;
- генераторы.
Эти возможности будут изучаться постепенно в следующих темах.
84. Основные правила урока
Функция с одним параметром:
def calculate_square_area(side_length):
return side_length ** 2
Вызов с одним аргументом:
calculate_square_area(5)
Функция с двумя параметрами:
def add_numbers(first_number, second_number):
return first_number + second_number
Вызов с двумя аргументами:
add_numbers(10, 5)
Первый аргумент попадает в первый параметр.
Второй аргумент попадает во второй параметр.
Параметры являются локальными именами функции.
Количество переданных аргументов должно соответствовать количеству обязательных параметров.
Подходящие типы данных определяются операциями внутри функции.
Результат можно вернуть напрямую:
return side_length ** 2
Или сначала сохранить:
area = side_length ** 2
return area
Функция является объектом, а её имя — ссылкой на этот объект.
Одинаковую логику лучше один раз поместить в функцию и затем переиспользовать:
DRY — Don't Repeat Yourself
В этой части аргументы намеренно передаются только по позиции; остальные способы передачи будут рассмотрены отдельно.