Переменные аргументов *args и **kwargs в функции Python
Передача произвольного числа аргументов в функцию Python
Наконец, наименее часто используемая опция, это когда функция вызываться с произвольным числом аргументов. Обычно они указываются последними в списке формальных параметров, потому что собирают все оставшиеся входные аргументы, которые передаются в функцию.
При определении функции, параметры с произвольным числом аргументов указывают как:
- *args — произвольное число позиционных аргументов. При вызове функции, на место этого параметра передается список аргументов, заключенных в кортеж. Перед *args может быть ноль или более нормальных аргументов. Любые формальные параметры, которые появляются после параметра *args , являются аргументами «только для ключевых слов». Это означает, что следующие за *args параметры могут использоваться только как ключевые аргументы, а не как позиционные.
- **kwargs — произвольное число именованных аргументов. При вызове функции, на его место передается список именованных аргументов заключенных в словарь, кроме тех, имена которых были определены ранее. Параметр **kwargs может быть определен совместно с другим формальным параметром *args . Параметр **kwargs указывается последним в области определения формальных параметров функции.
Примечание: один символ * в имени параметра функции args распаковывает список или кортеж для передачи позиционных аргументов, а два символа ** в имени параметра функции **kwargs распаковывает словарь для передачи ключевых аргументов в функцию при ее вызове.
Имена *args и **kwargs по негласному соглашению принято использовать в документации Python. На самом деле никто не запрещает брать любые другие имена переменных. Например, для словарей наряду c **kwargs иногда используют **options .
Пример использования *args :
def chees(*arguments): for arg in arguments: print(arg) word = ("It's very runny, sir.", "It's really very.", "VERY runny, sir.") chees(*word) # Выведет It's very runny, sir. It's really very. VERY runny, sir.
Пример использования **kwargs :
def shop(**keywords): for kw in keywords: print(kw, ":", keywords[kw]) kword = shopkeeper:"Michael Palin", client:"John Cleese", sketch:"Cheese Shop Sketch"> shop(**kword) # Выведет shopkeeper : Michael Palin client : John Cleese sketch : Cheese Shop Sketch
Распаковку можно использовать несколько раз. На примере словаря:
def process_data(a, b, c, d): print(a, b, c, d) x = 'a': 1, 'b': 2> y = 'c': 3, 'd': 4> process_data(**x, **y) 1 2 3 4 process_data(**x, c=23, d=42) 1 2 23 42
Пример совместного использования *args и **kwargs :
def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) for kw in keywords: print(kw, ":", keywords[kw])
Функцию cheeseshop можно вызвать так:
word = ("It's very runny, sir.", "It's really very.", "VERY runny, sir.") kword = shopkeeper:"Michael Palin", client:"John Cleese", sketch:"Cheese Shop Sketch"> cheeseshop("Limburger", *word, **kword)
и, конечно, функция выведет:
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very. VERY runny, sir. ---------------------------------------- shopkeeper : Michael Palin client : John Cleese sketch : Cheese Shop Sketch
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Функции это объекты
- Функции могут иметь атрибуты
- Функции могут храниться в структурах данных
- Функции могут быть вложенными
- Передача функции в качестве аргумента другой функции
- Область видимости переменных функции
- Операторы global и nonlocal
- Параметры (аргументы) функции
- Ключевые аргументы в определении функции Python
- Значение аргумента по умолчанию в функциях Python
- Варианты передачи аргументов в функцию Python
- Переменные аргументов *args и **kwargs в функции Python
- Распаковка аргументов для передачи в функцию Python
- Как оцениваются аргументы при вызове функции?
- Строгие правила передачи аргументов в функцию Python
- Инструкция return
- Анонимные функции (lambda-выражения)
- Строки документации в функциях Python
- Рекурсия
- Замыкания в функциях Python
- Перегрузка функций
Аргументы функции Python
Вы можете создать функцию на Python, которая принимает переменное количество аргументов. В этом посте вы узнаете, как определять такие функции, используя значения по умолчанию, ключевые слова и произвольные аргументы.
Аргументы
Мы узнали, как определить функцию и вызвать ее в теме пользовательской функции. В противном случае вызов функции завершится ошибкой. Вот иллюстрация.
def greet(name, msg): """This function greets to the person with the provided message""" print("Hello", name + ', ' + msg) greet("Monica", "Good morning!")
Hello Monica, Good morning!
Здесь функция greet() имеет два параметра.
Эта функция работает легко и без ошибок, потому что мы вызвали ее с двумя аргументами.
Интерпретатор выдаст сообщение об ошибке, если мы вызовем его с другим количеством аргументов. Ниже показан вызов этого метода с одним аргументом и без него, а также связанные с ним сообщения об ошибках.
>>> greet("Monica") # only one argument TypeError: greet() missing 1 required positional argument: 'msg'
>>> greet() # no arguments TypeError: greet() missing 2 required positional arguments: 'name' and 'msg'
Переменные аргументы функции
До сих пор у функций было заданное количество аргументов. В Python существуют и другие способы определения функции, которая может принимать переменное количество параметров.
Ниже описаны три различные формы этого типа.
Аргументы Python по умолчанию
Аргументы функций могут иметь значения по умолчанию в Python.
Используя оператор присваивания (=), мы можем присвоить аргументу значение по умолчанию. Вот иллюстрация.
def greet(name, msg="Good morning!"): """ This function greets to the person with the provided message. If the message is not provided, it defaults to "Good morning!" """ print("Hello", name + ', ' + msg) greet("Kate") greet("Bruce", "How do you do?")
Hello Kate, Good morning! Hello Bruce, How do you do?
Используя оператор присваивания (=), мы можем присвоить аргументу значение по умолчанию. Вот иллюстрация.
Параметр msg, напротив, имеет значение «Доброе утро!» как его значение по умолчанию. В результате этого не требуется во время вызова. Если указано значение, оно будет иметь приоритет над значением по умолчанию.
Значение по умолчанию может быть установлено для любого количества аргументов в функции. Однако, если у нас есть аргумент по умолчанию, мы также должны иметь значения по умолчанию для всех аргументов справа от него.
Другими словами, аргументы не по умолчанию не могут сопровождаться аргументами по умолчанию. Например, если заголовок функции был определен как:
def greet(msg = "Good morning!", name):
Мы получили бы ошибку как:
SyntaxError: non-default argument follows default argument
Аргументы ключевых слов Python
Вызовы функций связаны с аргументами ключевого слова. Когда вы используете аргументы ключевого слова в вызове функции, вызывающая сторона использует имя параметра для идентификации параметров.
Поскольку интерпретатор Python может использовать предоставленные ключевые слова для сопоставления значений с параметрами, вы можете пропустить аргументы или расположить их не по порядку. Метод printme() также можно вызывать с ключевыми словами следующими способами:
# 2 keyword arguments greet(name = "Bruce",msg = "How do you do?") # 2 keyword arguments (out of order) greet(msg = "How do you do?",name = "Bruce") 1 positional, 1 keyword argument greet("Bruce", msg = "How do you do?")
Как видно, во время вызова функции мы можем смешивать позиционные и ключевые аргументы. Однако мы должны помнить, что аргументы ключевого слова должны следовать после позиционных аргументов.
Будут проблемы, если позиционный аргумент используется после аргументов ключевого слова. Например, рассмотрим следующий вызов функции:
greet(name="Bruce","How do you do?")
Приведет к ошибке:
SyntaxError: non-keyword arg after keyword arg
Произвольные аргументы Python
Мы не всегда заранее знаем, сколько аргументов будет передано в функцию. Мы можем справиться с такими обстоятельствами в Python, вызывая функции с произвольным количеством аргументов.
Чтобы указать этот тип аргумента, мы используем звездочку (*) перед именем параметра в спецификации функции. Вот иллюстрация.
def greet(*names): """This function greets all the person in the names tuple.""" # names is a tuple with arguments for name in names: print("Hello", name) greet("Rocky", "Sunil", "Anil", "Bishal")
Hello Rocky Hello Sunil Hello Anil Hello Bishal
В этом случае мы вызвали функцию с многочисленными аргументами. Перед передачей в функцию эти аргументы упаковываются в запись. Мы используем цикл for внутри метода, чтобы вернуть все аргументы.
Параметры и аргументы функции
В программировании функции могут не только возвращать данные, но также принимать их, что реализуется с помощью так называемых параметров, которые указываются в скобках в заголовке функции. Количество параметров может быть любым.
Параметры представляют собой локальные переменные, которым присваиваются значения в момент вызова функции. Конкретные значения, которые передаются в функцию при ее вызове, будем называть аргументами. Следует иметь в виду, что встречается иная терминология. Например, формальные параметры и фактические параметры. В 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. Введение в программирование
Позиционные аргументы — Python: Функции
У функций, которые мы изучали ранее, были в основном позиционные аргументы. Когда мы вызываем такие функции, значения в их аргументы подставляются согласно позиции их имен в определении функции. Например, мы вызываем следующую функцию:
def add(x, y): return x + y
В этом случае с аргументами (10, 20) аргумент x получит значение 10 , а y — 20 .
Функция не всегда должна получать фиксированное количество аргументов. Когда нам нужна большая гибкость, мы можем передать в нее неограниченное количество аргументов. В этом уроке мы узнаем, как объявлять функции с разным количеством аргументов, и как передавать функции аргументы, которые упакованы в коллекцию.
Переменное количество аргументов
Функция print принимает то количество аргументов, которые мы ей передадим. Она даже работает, когда ее вызывают без аргументов.
Рассмотрим пример функции с неограниченным количеством аргументов:
def f(*args): print(type(args)) print(args) f() # => tuple # => () f(1, 'a', None, False) # => tuple # => (1, 'a', None, False)
Эта функция отличается от функции с позиционными аргументами аргументом *args . Точнее оператором * . Он упаковывает все передаваемые в функцию аргументы от текущей позиции и до конца в переменную как кортеж.
Аргумент с оператором * забирает в себя все переданные значения. Если мы хотим использовать дополнительные аргументы, их нужно указать перед аргументом с оператором * , как показано в примере:
def f(x, *args): print(f'Первый аргумент: x>') for a in args: print(f'Другой аргумент из *args a>!') f('Programing language', 'Python', 'PHP', 'Java') # => Первый аргумент: Programing language # => Другой аргумент из *args Python! # => Другой аргумент из *args PHP! # => Другой аргумент из *args Java! f() # TypeError: f() missing 1 required positional argument: 'x'
Здесь функция принимает несколько аргументов, но как минимум один должен быть передан всегда. Первый аргумент станет значением переменной x , а остальные сохранятся в *args . Так можно делать любое нужное количество обязательных аргументов.
Передача аргументов в форме коллекции
Иногда нужно сначала сформировать набор аргументов, а потом передать их функции. Допустим, прочитать аргументы из файла или получить другим программным способом. Здесь снова пригодится оператор * :
def sum(a, b): return a + b nums = [3, 4] sum(*nums) # 7
Часть аргументов можно подставлять сразу в функцию и даже подставлять несколько коллекций сразу:
def greet(*names): for name in names: print(f'Hello, name>!') greet( 'Bob', *['Mary', 'Clair'], 'Sam', *('Henry', 'John') ) # => Hello, Bob! # => Hello, Mary! # => Hello, Clair! # => Hello, Sam! # => Hello, Henry! # => Hello, John!
В приведенном примере мы передали в функцию greet набор аргументов и коллекций. При помощи оператора * функция greet вызывается с шестью аргументами: ‘Bob’, ‘Mary’, ‘Clair’, ‘Sam’, ‘Henry’ и ‘John’. Результатом этого кода будет шесть приветствий по одному для каждого аргумента. Они будут в том порядке, в котором их передали в функцию.
Выводы
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
