Параметры (аргументы) функции
Функции могут не только возвращать данные, но также принимают их, что реализуется с помощью так называемых параметров, которые указываются в скобках в заголовке функции. Количество параметров может быть любым, также существует несколько вариантов передачи аргументов в функцию
Параметры функции представляют собой локальные переменные, которым присваиваются значения в момент ее вызова. Иногда у параметрам задают значения (аргументы), используемые по умолчанию. Конкретные значения, которые передаются в функцию при ее вызове, называются аргументами.
Каждый раз, когда вызывается функция, создается новая область видимости для хранения локальных переменных этой функции и каждое имя передаваемого параметра связывается со значениями в новом локальном пространстве имен. Когда функция возвращает значение или завершает выполнение иным способом, это пространство имен уничтожается.
Параметры (аргументы) функции передаются в локальную область видимости с использованием вызова по значению, где значение всегда является ссылкой на объект, а не значением объекта.
def func (a, b): a = a * b b = a / 2 return a + b n1 = 10 n2 = 5 rez = func(n1, n2) print(rez) print(n1, n2) # напечатает 75,0 10 5
Изменение значений a и b в теле функции никак не скажется на значениях переменных n1 и n2 , определенных в глобальном пространстве. Они останутся прежними. Говорят, что в функцию данные передаются по значению. Когда a присваивалось число 10, то это было уже другое число, не то, на которое ссылается переменная n1 . Число 10 было скопировано и помещено в отдельную ячейку памяти для переменной a .
Необходимость передачи по ссылке связана в первую очередь с экономией памяти. Сложные типы данных, по сути представляющие собой структуры данных, обычно копировать не целесообразно. Однако, если надо, всегда можно сделать это принудительно.
Какие бывают аргументы/параметры в функциях Python.
Аргумент — это значение, передаваемое функции (или методу) при вызове функции.
Есть два типа аргументов:
-
ключевой аргумент: аргумент, которому предшествует идентификатор (например, name= ) в вызове функции или переданный как значение в словаре, которому предшествует две звездочки ** — обозначение распаковки словаря. Например, 3 и 5 являются аргументами ключевого слова в следующих вызовах встроенной функции complex() :
# передача значений ключевым # аргументам функции complex(real=3, imag=5) dict_args ='real': 3, 'imag': 5> # передача словаря со значениями # ключевых аргументов complex(**dict_args)
# передача значений позиционным # аргументам функции complex(3, 5) tuple_args = (3, 5) # передача кортежа со значениями # позиционных аргументов complex(*tuple_args)
Аргументы назначаются именованным локальным переменным в теле функции. Смотрите правила, регулирующие это назначение в разделе «Что происходит при вызове функции?».
Синтаксически, для представления аргумента может использоваться любое выражение, а оцененное значение присваивается локальной переменной.
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Функции это объекты
- Функции могут иметь атрибуты
- Функции могут храниться в структурах данных
- Функции могут быть вложенными
- Передача функции в качестве аргумента другой функции
- Область видимости переменных функции
- Операторы global и nonlocal
- Параметры (аргументы) функции
- Ключевые аргументы в определении функции Python
- Значение аргумента по умолчанию в функциях Python
- Варианты передачи аргументов в функцию Python
- Переменные аргументов *args и **kwargs в функции Python
- Распаковка аргументов для передачи в функцию Python
- Как оцениваются аргументы при вызове функции?
- Строгие правила передачи аргументов в функцию Python
- Инструкция return
- Анонимные функции (lambda-выражения)
- Строки документации в функциях Python
- Рекурсия
- Замыкания в функциях Python
- Перегрузка функций
3. Функции¶
В программировании функцией называют именованную последовательность предложений, которая выполняет некоторые действия. Выполняемые действия описываются в определении функции.
В Python функция определяется так:
def имя(список параметров): предложения
Можно давать создаваемым функциям любые имена, нужно только помнить, что использовать ключевые слова в качестве имен нельзя. Список параметров указывает, какую информацию, если она вообще нужна, пользователь должен передать функции.
Внутри функции может быть сколько угодно предложений, причем все они должны иметь отступ вправо относительно def . В примерах в этой книге используется стандартный отступ в 4 пробела. Определение функции — это первое из нескольких составных предложений, которые мы увидим; все они строятся по такой схеме:
- Заголовок, который начинается с ключевого слова и заканчивается двоеточием.
- Тело, состоящее из одного или более предложений Python, имеющих одинаковый отступ — 4 пробела по стандарту Python — относительно заголовка.
В определении функции ключевое слово в заголовке — это def . За ним следуют имя функции и список параметров, заключенный в скобки. Список параметров может быть пустым или может содержать любое число параметров. В любом случае скобки необходимы.
Первые две функции, которые мы напишем, не имеют параметров.
def new_line(): print
Эта функция имеет имя new_line . Пустые скобки показывают, что функция не имеет параметров. Ее тело содержит единственное предложение, которое выводит символ новой строки. (Именно это происходит, когда вы используете print без аргументов.)
Определение новой функции не приводит автоматически к выполнению этой функции. Чтобы выполнить функцию, нужно сделать вызов функции. Для вызова функции записывают имя функции, за которым в скобках следует список аргументов. При вызове функции аргументы присваиваются параметрам из определения функции.
В наших первых примерах функции имеют пустой список параметров, так что вызов функции не требует аргументов. Заметьте, однако, что в вызове функции скобки необходимы:
print "First Line." new_line() print "Second Line."
Эта программа выводит:
First line. Second line.
Дополнительное пространство между двумя строками — это результат вызова функции new_line() . А что если нам понадобится больше свободного места между строками? В таком случае мы могли бы вызвать одну и ту же функцию несколько раз:
print "First Line." new_line() new_line() new_line() print "Second Line."
Или мы могли бы написать новую функцию с именем three_lines , которая выводит три символа новой строки:
def three_lines(): new_line() new_line() new_line() print "First Line." three_lines() print "Second Line."
Эта функция содержит три предложения, каждое из которых записано с отступом в 4 пробела. Поскольку следующее предложение не имеет отступа, Python понимает, что оно не является частью определения функции.
Стоит заметить несколько вещей в связи с этой программой:
- Одну и ту же функцию можно вызывать многократно. Так обычно и происходит.
- Одна функция может вызывать другую; в нашем примере three_lines вызывает new_line .
Для чего нужно утруждать себя созданием новых функций? Для этого есть много причин, и рассмотренный пример демонстрирует две из них:
- Создание функции позволяет вам дать имя группе предложений. Функции могут упростить программу, скрывая сложные вычисления за единственным вызовом функции и предлагая понятные, говорящие сами за себя, имена вместо непонятного на первый взгляд кода.
- Создание новой функции может сделать программу меньше за счет исключения повторяющегося кода. Например, короткий способ напечатать девять последовательных символов новой строки — это вызвать three_lines три раза.
Соберем вместе фрагменты кода из этого раздела в скрипт tryme1.py :
def new_line(): print def three_lines(): new_line() new_line() new_line() print "First Line." three_lines() print "Second Line."
В этой программе определяются две функции: new_line и three_lines . Составное предложение def , определяющее функцию, выполняются так же, как и другие предложения, а его результатом является создание новой функции. Предложения в теле функции не выполняются до тех пор, пока функция не будет вызвана.
Прежде чем выполнить функцию, ее нужно создать. Другими словами, определение функции должно выполняться прежде, чем в программе встречается первый вызов этой функции.
3.2. Поток выполнения¶
Чтобы быть уверенным, что функция определена прежде, чем вызывается, нужно знать порядок, в котором выполняются предложения. Порядок выполнения предложений в программе называется потоком выполнения.
Выполнение всегда начинается с первой строки программы. Предложения выполняются по одному за раз, сверху вниз.
Определения функций не нарушают поток выполнения программы, но предложения внутри функций не выполняются до тех пор, пока функция не вызвана. Хотя это нечасто используется, но можно определить одну функцию внутри другой. В этом случае, внутреннее определение не выполнится до тех пор, пока не будет вызвана внешняя функция.
Вызов функции — как объезд в потоке выполнения. Вместо того, чтобы перейти к следующему предложению, выполняется переход на первое предложение тела функции, выполняются предложения тела функции, и затем выполняется возврат туда, откуда был сделан вызов функции.
Выглядит достаточно просто, пока вы не вспомните о том, что одна функция может вызывать другую. А эта другая может вызывать третью, и так далее!
Но Python точно “знает”, откуда вызвана текущая выполняемая функция, так что каждый раз, когда функция завершается, программа продолжается с того места, где она была перед вызовом функции. Когда достигнут конец программы, она завершается.
В чем здесь мораль? Когда читаете программу, не читайте ее просто сверху вниз. Следуйте за потоком выполнения.
3.3. Параметры, аргументы и предложение import ¶
Большинству функций нужны аргументы — значения, которые используются функцией для ее работы. Например, если вы хотите найти абсолютное значение числа, то нужно указать, какого именно числа. В Python имеется встроенная функция для вычисления абсолютного значения числа:
>>> abs(5) 5 >>> abs(-5) 5
В этом примере, аргументами функции abs являются 5 и -5.
Некоторые функции принимают больше одного аргумента. Например, встроенная функция pow берет два аргумента, основание и степень. Внутри функции передаваемые в нее значения присваиваются переменным, которые называются параметры.
>>> pow(2, 3) 8 >>> pow(7, 4) 2401
Другая встроенная функция, принимающая больше одного аргумента, — функция max .
>>> max(7, 11) 11 >>> max(4, 1, 17, 2, 12) 17 >>> max(3 * 11, 5**3, 512 - 9, 1024**0) 503
В функцию max можно передать любое число аргументов, разделенных запятыми; функция вернет максимальное из переданных ей значений. Аргументами могут быть как простые значения, так и выражения. В последнем примере функция вернула 503, поскольку 503 больше, чем 33, 125 и 1.
А вот пример определенной пользователем функции с одним параметром:
def print_twice(bruce): print bruce, bruce
Эта функция принимает единственный аргумент и присваивает его значение параметру с именем bruce . Значение параметра (определяя функцию, мы понятия не имеем, какое именно это значение) выводится дважды, после чего выводится символ новой строки. Имя bruce здесь просто демонстрирует, что вы можете дать параметру какое угодно имя. Но будет правильным давать параметрам более информативные имена, чем bruce .
Интерактивный режим интерпретатора Python предоставляет удобную среду для тестирования ваших функций. Можно воспользоваться предложением import чтобы загрузить функции, определенные в скрипте, в сеанс интерпретатора.
Предположим, что функция print_twice определена в скрипте с именем chap03.py . Тогда мы сможем работать с ней в интерактивном режиме, импортировав ее в сеанс Python:
>>> from chap03 import * >>> print_twice('Spam') Spam Spam >>> print_twice(5) 5 5 >>> print_twice(3.14159) 3.14159 3.14159
При вызове функции значение аргумента присваивается соответствующему параметру из определения функции. Все выглядит так, как будто при вызове print_twice('Spam') выполняется bruce = 'Spam' , при вызове print_twice(5) выполняется bruce = 5 , а при вызове print_twice(3.14159) выполняется bruce = 3.14159 .
Значение любого типа, которое может быть напечатано, можно передать в функцию print_twice . В первом вызове функции в приведенном примере аргумент является строкой. Во втором — целым числом. А в третьем — числом с плавающей точкой.
Как и в случае со встроенными функциями, в качестве аргумента для print_twice можно использовать выражение:
>>> print_twice('Spam' * 4) SpamSpamSpamSpam SpamSpamSpamSpam
Вначале вычисляется выражение 'Spam'*4 , что дает значение 'SpamSpamSpamSpam' , а затем это значение передается в функцию print_twice как аргумент.
3.4. Композиция¶
Как и в математике, функции в Python можно комбинировать, то есть, использовать результат одной функции в качестве аргумента при вызове другой.
>>> print_twice(abs(-7)) 7 7 >>> print_twice(max(3, 1, abs(-11), 7)) 11 11
В первом случае abs(-7) дает значение 7, которое становится аргументом для print_twice . Во втором случае у нас двухуровневая композиция, так как сначала вычисляется abs(-11) , что дает 11, затем вычисление max(3, 1, 11, 7) дает 11 и, наконец, print_twice(11) отображает результат.
В качестве аргумента можно использовать переменную:
>>> michael = 'Eric, the half a bee.' >>> print_twice(michael) Eric, the half a bee. Eric, the half a bee.
Сделаем важное замечание. Имя переменной, которое мы указываем в качестве аргумента ( michael ) не имеет никакого отношения к имени параметра ( bruce ). Абсолютно все равно, с каким именем связано значение в том месте программы, откуда оно передается в функцию; внутри функции print_twice мы зовем его bruce .
3.5. Переменные и параметры являются локальными¶
Когда вы создаете локальную переменную внутри функции, она существует только внутри функции, и её невозможно использовать снаружи. Например:
def cat_twice(part1, part2): cat = part1 + part2 print_twice(cat)
Эта функция принимает два аргумента, конкатенирует их и затем дважды печатает результат. Можно вызвать эту функцию с двумя строками:
>>> chant1 = "Pie Jesu domine, " >>> chant2 = "Dona eis requiem." >>> cat_twice(chant1, chant2) Pie Jesu domine, Dona eis requiem. Pie Jesu domine, Dona eis requiem.
Когда завершается cat_twice , переменная cat уничтожается. Если попробовать вывести ее, то получим ошибку:
>>> print cat NameError: name 'cat' is not defined
Параметры также являются локальными. Например, снаружи функции print_twice не существует такой вещи, как bruce . Если попробовать её использовать, Python выдаст сообщение об ошибке.
3.6. Стековые диаграммы¶
Для того, чтобы отследить, какую переменную где можно использовать, иногда полезно нарисовать стековую диаграмму. (По-английски стек означает кипу или штабель, то есть, некоторое количество однородных предметов, положенных один на другой.) Как и диаграмма из предыдущей главы, стековые диаграммы показывают значение каждой переменной, но, кроме того, они показывают функцию, которой принадлежит каждая переменная.
Каждая функция представлена прямоугольником, возле которого записано имя функции, а внутри записаны имена ее параметров и переменных. Стековая диаграмма для предыдущего примера выглядит так:

Порядок размещения функций в стеке показывает поток выполнения. print_twice вызывается функцией cat_twice , а cat_twice вызывается из __main__ . Это специальное имя для функции самого верхнего уровня. Когда создается переменная вне каких-либо функций, она принадлежит __main__ .
Каждый параметр функции имеет то же значение, что и соответствующий ему аргумент. Так, значение part1 то же, что у chant1 , part2 — то же, что у chant2 и bruce — то же, что у cat .
Если во время выполнения функции происходит ошибка, Python печатает имя выполнявшейся функции, а также имя функции, которая ее вызвала, а также имя функции, которая вызвала эту функцию, и так далее, до функции самого верхнего уровня.
Чтобы посмотреть, как это работает, создайте скрипт Python с именем tryme2.py и следующим содержанием:
def print_twice(bruce): print bruce, bruce print cat def cat_twice(part1, part2): cat = part1 + part2 print_twice(cat) chant1 = "Pie Jesu domine, " chant2 = "Dona eis requim." cat_twice(chant1, chant2)
Мы добавили предложение print cat в функцию print_twice , но переменная cat там не определена. Выполнение этого скрипта приведет к сообщению об ошибке, похожему на это:
Traceback (innermost last): File "tryme2.py", line 11, in module> cat_twice(chant1, chant2) File "tryme2.py", line 7, in cat_twice print_twice(cat) File "tryme2.py", line 3, in print_twice print cat NameError: global name 'cat' is not defined
Этот список называется трассировкой стека. Он содержит информацию о том, в каком файле произошла ошибка, и какая строка какой функции выполнялась в это время. Он также показывает строку кода, вызвавшую ошибку.
Обратите внимание на сходство между трассировкой стека и стековой диаграммой. Это не случайное совпадение, так как в основе обеих лежит один и тот же механизм.
3.7. Глоссарий¶
Предложение, позволяющее сделать функции и переменные, определенные в скрипте Python, доступными при выполнении другого скрипта или в интерактивном режиме Python. Например, пусть имеется скрипт с именем tryme.py :
def print_thrice(thing): print thing, thing, thing n = 42 s = "And now for something completely different. "
Теперь запустим интерпретатор в той директории, где размещается tryme.py :
$ ls tryme.py $ python >>>
В tryme.py определены три имени: print_thrice , n , и s . Если попробовать использовать их, не выполнив импорт, то получим ошибку:
>>> n Traceback (most recent call last): File "", line 1, in NameError: name 'n' is not defined >>> print_thrice("ouch!") Traceback (most recent call last): File "", line 1, in NameError: name 'print_thrice' is not defined
Если, однако, импортировать всё из tryme.py , то можно будет использовать всё, что в нем определено:
>>> from tryme import * >>> n 42 >>> s 'And now for something completely different. ' >>> print_thrice("Yipee!") Yipee! Yipee! Yipee! >>>
Заметьте, что не нужно включать .py в имя скрипта в предложении import.
аргумент Значение, передаваемое функции при ее вызове. Это значение присваивается соответствующему параметру функции. вызов функции Предложение, выполняющее функцию. Оно состоит из имени функции, за которым следует список аргументов в скобках. заголовок составного предложения Первая часть составного предложения. Заголовки начинаются с ключевого слова и заканчиваются двоеточием. композиция функций Использование вызова функции в качестве аргумента при вызове другой функции. локальная переменная Переменная, определенная внутри функции. Локальная переменная может использоваться только внутри функции. определение функции Составное предложение, которое создает новую функцию, указывая ее имя, параметры и выполняемые предложения. параметр Имя, используемое внутри функции для доступа к значению, переданному в качестве аргумента. поток выполнения Порядок, в котором выполняются предложения во время выполнения программы. составное предложение
Предложение, состоящее из двух частей:
- заголовок — начинается с ключевого слова, задающего тип составного предложения, и заканчивается двоеточием.
- тело — содержит одно или более предложений, имеющих одинаковый отступ относительно заголовка.
Составное предложение строится так:
keyword expression: statement statement .
стековая диаграмма Графическое представление стека (кипы, стопки) вызываемых функций, их переменных и параметров. тело составного предложения Вторая часть составного предложения. Тело состоит из последовательности предложений, имеющих одинаковый отступ относительно заголовка. Стандартный отступ для программ на Python составляет 4 пробела. трассировка стека Список выполняющихся функций, печатаемый при возникновении ошибки выполнения. Трассировка стека перечисляет функции в порядке, в котором они вызывались. функция Именованная последовательность предложений, которая выполняет некоторые полезные действия. Функции могут иметь или не иметь параметры, могут возвращать или не возвращать результат.
3.8. Упражнения¶
- С помощью текстового редактора создайте скрипт Python с именем tryme3.py . Поместите в него функцию nine_lines , которая использует three_lines чтобы выводить девять пустых строк. Теперь добавьте функцию clear_screen , которая выводит 25 пустых строк. В последней строке вашей программы напишите вызовclear_screen .
- Переместите последнюю строку в tryme3.py в начало программы, так, чтобы вызов функцииclear_screen находился перед определением функции. Запустите программу и заметьте, какое сообщение об ошибке вы получили. Можете сформулировать правило о том, как должны располагаться в программе определения функций и вызовы функций относительно друг друга?
- Вернувшись к рабочей версии tryme3.py , поместите определение функции new_line после определения функции three_lines . Посмотрите, что произойдет, когда вы запустите эту программу. Теперь поместите определение new_line ниже вызова three_lines() . Объясните, как поведение программы иллюстрирует правило, сформулированное в предыдущем примере.
- Напишите тело в определении функцииcat_n_times так, чтобы строка s печаталась n раз:
def cat_n_times(s, n): fill in your code here>
Сохраните эту функцию в скрипте с именем import_test.py . Находясь в той директории, в которой сохранен файл (команда ls в Unix должна показать import_test.py ), запустите интерпретатор Python в интерактивном режиме и попробуйте выполнить следующее:
>>> from import_test import * >>> cat_n_times('Spam', 7) SpamSpamSpamSpamSpamSpamSpam
Параметры и аргументы функции
В программировании функции могут не только возвращать данные, но также принимать их, что реализуется с помощью так называемых параметров, которые указываются в скобках в заголовке функции. Количество параметров может быть любым.
Параметры представляют собой локальные переменные, которым присваиваются значения в момент вызова функции. Конкретные значения, которые передаются в функцию при ее вызове, будем называть аргументами. Следует иметь в виду, что встречается иная терминология. Например, формальные параметры и фактические параметры. В Python же обычно все называют аргументами.
Рассмотрим схему и поясняющий ее пример:
Когда функция вызывается, то ей передаются аргументы. В примере указаны глобальные переменные num1 и num2 . Однако на самом деле передаются не эти переменные, а их значения. В данном случае числа 100 и 12. Другими словами, мы могли бы писать mathem(100, 12) . Разницы не было бы.
Когда интерпретатор переходит к функции, чтобы начать ее исполнение, он присваивает переменным-параметрам переданные в функцию значения-аргументы. В примере переменной a будет присвоено 100, b будет присвоено 12.
Изменение значений a и b в теле функции никак не скажется на значениях переменных num1 и num2 . Они останутся прежними. В Python такое поведение характерно для неизменяемых типов данных, к которым относятся, например, числа и строки. Говорят, что в функцию данные передаются по значению. Можно сказать, когда a присваивалось число 100, то это было уже другое число, не то, на которое ссылается переменная num1 . Число 100 было скопировано и помещено в отдельную ячейку памяти для переменной a .
На самом деле переменная a в момент присваивания значения может указывать на то же число 100, что и переменная num1 . Однако, когда a в результате вычислений в теле функции получает новое значение, то связывается с другой ячейкой памяти, потому что числа относятся к неизменяемым типам данных, то есть нельзя переписать значение содержащей их ячейки. При этом переменная num1 остается связанной со старым значением.
Существуют изменяемые типы данных. Для Питона, это, например, списки и словари. В этом случае данные передаются по ссылке. В функцию передается ссылка на них, а не сами данные. И эта ссылка связывается с локальной переменной. Изменения таких данных через локальную переменную обнаруживаются при обращении к ним через глобальную. Это есть следствие того, что несколько переменных ссылаются на одни и те же данные, на одну и ту же область памяти.
Необходимость передачи по ссылке связана в первую очередь с экономией памяти. Сложные типы данных, по сути представляющие собой структуры данных, обычно копировать не целесообразно. Однако, если надо, всегда можно сделать это принудительно.
Произвольное количество аргументов
Обратим внимание еще на один момент. Количество аргументов и параметров совпадает. Нельзя передать три аргумента, если функция принимает только два. Нельзя передать один аргумент, если функция требует два обязательных. В рассмотренном примере они обязательные.
Однако в 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 few_or_many(*a): print(a) few_or_many(1) few_or_many('1', 1, 2, 'abc') few_or_many()
(1,) ('1', 1, 2, 'abc') ()
Опять же, судя по скобкам, здесь возникает упомянутый в прошлом уроке кортеж.
Практическая работа
Напишите программу, в которой определена функция int_test , имеющая один параметр. Функция проверяет, можно ли переданное ей значение преобразовать к целому числу. Если можно, возвращает логическое True . Если нельзя – False .
В основной ветке программы присвойте переменной s то, что пользователь вводит с клавиатуры. Вызовите функцию int_test() , передав ей значение s . Если функция возвращает истину, преобразуйте строку s в число n и выведите на экран значение n + 10 .
Примеры решения и дополнительные уроки в pdf-версии курса
X Скрыть Наверх
Python. Введение в программирование
Как называются значения которые указывают при вызове функции
Функция может принимать параметры. Через параметры в функцию можно передавать данные. Банальный пример — функция print() , которая с помощью параметра принимает значение, выводимое на консоль.
Теперь определим и используем свою функцию с параметрами:
def say_hello(name): print(f"Hello, ") say_hello("Tom") say_hello("Bob") say_hello("Alice")
Функция say_hello имеет параметр name, и при вызове функции мы можем передать этому параметру какой-либо значение. Внутри функции мы можем использовать параметр как обычную переменную, например, вывести значение этого параметра на консоль функцией print. Так, в выражении:
say_hello("Tom")
Строка «Tom» будет передаваться параметру name. В итоге при выполнении программы мы получим следующий консольный вывод:
Hello, Tom Hello, Bob Hello, Alice
При вызове функции значения передаются параметрам по позиции. Например, определим и вызовем функцию с несколькими параметрами:
def print_person(name, age): print(f"Name: ") print(f"Age: ") print_person("Tom", 37)
Здесь функция print_person принимает два параметра: name и age. При вызове функции:
print_person("Tom", 37)
Первое значение — «Tom» передается первому параметру, то есть параметру name . Второе значение — 37 передается второму параметру — age. И внутри функции значения параметров выводятся на консоль:
Name: Tom Age: 37
Значения по умолчанию
Некоторые параметры функции мы можем сделать необязательными, указав для них значения по умолчанию при определении функции. Например:
def say_hello(name="Tom"): print(f"Hello, ") say_hello() # здесь параметр name будет иметь значение "Tom" say_hello("Bob") # здесь name = "Bob"
Здесь параметр name является необязательным. И если мы не передаем при вызове функции для него значение, то применяется значение по умолчанию, то есть строка «Tom». Консольный вывод данной программы:
Hello, Tom Hello, Bob
Если функция имеет несколько параметров, то необязательные параметры должны идти после обязательных. Например:
def print_person(name, age = 18): print(f"Name: Age: ") print_person("Bob") print_person("Tom", 37)
Здесь параметр age является необязательным и по умолчанию имеет значение 18. Перед ним расположен обязательный параметр name. Поэтому при вызове функции мы можем не передавать значение параметру age, но параметру name передать значение необходимо.
При необходимости мы можем сделать все параметры необязательными:
def print_person(name = "Tom", age = 18): print(f"Name: Age: ") print_person() # Name: Tom Age: 18 print_person("Bob") # Name: Bob Age: 18 print_person("Sam", 37) # Name: Sam Age: 37
Передача значений параметрам по имени. Именованные параметры
В примерах выше при вызове функции значения передаются параметрами функции по позиции. Но также можно передавать значения параметрам по имени. Для этого при вызове функции указывается имя параметра и ему присваивается значение:
def print_person(name, age): print(f"Name: Age: ") print_person(age = 22, name = "Tom")
В данном случае значения параметрам age и name передаются по имени. И несмотря на то, что параметр name идет первым в определении функции, мы можем при вызове функции написать print_person(age = 22, name = «Tom») и таким образом передать число 22 параметру age, а строку «Tom» параметру name.
Символ * позволяет установить, какие параметры будут именнованными — то есть такие параметры, которым можно передать значения только по имени. Все параметры, которые располагаются справа от символа * , получают значения только по имени :
def print_person(name, *, age, company): print(f"Name: Age: Company: ") print_person("Bob", age = 41, company ="Microsoft") # Name: Bob Age: 41 company: Microsoft
В данном случае параметры age и company являются именнованными.
Можно сделать все параметры именнованными, поставив перед списком параметров символ *:
def print_person(*, name, age, company): print(f"Name: Age: Company: ")
Если наоборот надо определить параметры, которым можно передавать значения только по позиции, то есть позиционные параметры, то можно использовать символ / : все параметры, которые идут до символа / , являются позиционными и могут получать значения только по позиции
def print_person(name, /, age, company="Microsoft"): print(f"Name: Age: Company: ") print_person("Tom", company="JetBrains", age = 24) # Name: Tom Age: 24 company: JetBrains print_person("Bob", 41) # Name: Bob Age: 41 company: Microsoft
В данном случае параметр name является позиционным.
Для одной функции можно определять одновременно позиционные и именнованные параметры.
def print_person(name, /, age = 18, *, company): print(f"Name: Age: Company: ") print_person("Sam", company ="Google") # Name: Sam Age: 18 company: Google print_person("Tom", 37, company ="JetBrains") # Name: Tom Age: 37 company: JetBrains print_person("Bob", company ="Microsoft", age = 42) # Name: Bob Age: 42 company: Microsoft
В данном случае параметр name располагается слева от символа /, поэтому является позиционным и обязательным — ему можно передать значение только по позиции.
Параметр company является именнованным, так как располагается справа от символа *. Параметр age может получать значение по имени и по позиции.
Неопределенное количество параметров
С помощью символа звездочки можно определить параметр, через который можно передавать неопределенное количество значений. Это может быть полезно, когда мы хотим, чтобы функция получала несколько значений, но мы точно не знаем, сколько именно. Например, определим функцию подсчета суммы чисел:
def sum(*numbers): result = 0 for n in numbers: result += n print(f"sum = ") sum(1, 2, 3, 4, 5) # sum = 15 sum(3, 4, 5, 6) # sum = 18
В данном случае функция sum принимает один параметр — *numbers , но звездочка перед названием параметра указывает, что фактически на место этого параметра мы можем передать неопределенное количество значений или набор значений. В самой функции с помощью цикла for можно пройтись по этому набору, получить каждое значение из этого набора в переменную n и произвести с ним какие-нибудь действия. Например, в данном случае вычисляется сумма переданных чисел.