В следующих определениях методов, что делает *
и **
для чего param2
?
def foo(param1, *param2):
def bar(param1, **param2):
В следующих определениях методов, что делает *
и **
для чего param2
?
def foo(param1, *param2):
def bar(param1, **param2):
def func(*args)
). Для вопроса , спрашивая , что это означает , что в функции вызовов (func(*[1,2])
) см здесь . С вопросом, как распаковать списки аргументов, можно ознакомиться здесь . С вопросом о том, что*
означает литерал ([*[1, 2]]
), можно ознакомиться здесь .Ответы:
*args
И**kwargs
является общим идиома , чтобы произвольное число аргументов функций , как описано в разделе более об определении функций в документации на Python.В результате
*args
вы получите все параметры функции в виде кортежа :Команда
**kwargs
выдаст вам все ключевые аргументы, кроме тех, которые соответствуют формальному параметру в качестве словаря.Обе идиомы могут быть смешаны с обычными аргументами, чтобы позволить набор фиксированных и некоторых переменных аргументов:
Также возможно использовать это наоборот:
Другое использование этой
*l
идиомы - распаковка списков аргументов при вызове функции.В Python 3 можно использовать
*l
в левой части назначения ( Extended Iterable Unpacking ), хотя в этом контексте он дает список вместо кортежа:Также Python 3 добавляет новую семантику (см. PEP 3102 ):
Такая функция принимает только 3 позиционных аргумента, и все после
*
может быть передано только как ключевые аргументы.источник
**kwargs
теперь соответствует порядку, в котором аргументы ключевых слов были переданы функции». - docs.python.org/3/whatsnew/3.6.html Фактически, все диктанты в CPython 3.6 будут помнить порядок вставки в качестве детали реализации, это становится стандартным в Python 3.7.got an unexpected keyword argument 'name'
Также стоит отметить, что вы можете использовать
*
и**
при вызове функций. Это ярлык, который позволяет передавать несколько аргументов функции напрямую, используя список / кортеж или словарь. Например, если у вас есть следующая функция:Вы можете делать такие вещи, как:
Примечание: ключи
mydict
должны быть названы точно так же, как параметры функцииfoo
. В противном случае он выдастTypeError
:источник
Один * означает, что может быть любое количество дополнительных позиционных аргументов.
foo()
может быть вызван какfoo(1,2,3,4,5)
. В теле функции foo () param2 есть последовательность, содержащая 2-5.Двойной ** означает, что может быть любое количество дополнительных именованных параметров.
bar()
может быть вызван какbar(1, a=2, b=3)
. В теле bar () param2 находится словарь, содержащий {'a': 2, 'b': 3}С помощью следующего кода:
выход
источник
foobar(param1, *param2, **param3)
для полноты ответа необходим дополнительный пример с .Они позволяют определенным функциям принимать и пользователям передавать любое количество аргументов, positional (
*
) и keyword (**
).Определение функций
*args
допускает любое количество необязательных позиционных аргументов (параметров), которые будут назначены кортежу с именемargs
.**kwargs
допускает любое количество необязательных аргументов ключевого слова (параметров), которые будут в диктовке с именемkwargs
.Вы можете (и должны) выбрать любое подходящее имя, но если намерение состоит в том, чтобы аргументы имели неспецифическую семантику,
args
иkwargs
являлись стандартными именами.Расширение, передавая любое количество аргументов
Вы также можете использовать
*args
и**kwargs
для передачи параметров из списков (или любых повторяемых) и dicts (или любого отображения), соответственно.Функция получения параметров не должна знать, что они расширяются.
Например, xrange Python 2 явно не ожидает
*args
, но так как он принимает 3 целых числа в качестве аргументов:В качестве другого примера, мы можем использовать расширение dict в
str.format
:Новое в Python 3: определение функций с аргументами только из ключевых слов
Вы можете иметь только ключевые слова аргументы после
*args
- например, здесь,kwarg2
должны быть заданы в качестве ключевого аргумента - не позиционно:Применение:
Кроме того,
*
может использоваться сам по себе, чтобы указать, что за ключевым словом следуют только аргументы, без учета неограниченных позиционных аргументов.Здесь
kwarg2
снова должен быть явно заданный аргумент ключевого слова:И мы больше не можем принимать неограниченные позиционные аргументы, потому что у нас нет
*args*
:Опять же, проще говоря, здесь нам нужно
kwarg
дать имя, а не позиционно:В этом примере мы видим, что если мы пытаемся пройти
kwarg
позиционно, мы получаем ошибку:Мы должны явно передать
kwarg
параметр в качестве ключевого аргумента.Python 2 совместимые демки
*args
( как правило , сказал , что «звезда-арг») и**kwargs
(звезды могут подразумеваться, говоря «kwargs», но будет явно «двойной звезды kwargs») являются общими идиомы Python для используя*
и**
обозначения. Эти конкретные имена переменных не требуются (например, вы можете использовать*foos
и**bars
), но отход от соглашения может привести в ярость ваших коллег-программистов Python.Мы обычно используем их, когда не знаем, что получит наша функция или сколько аргументов мы можем передать, а иногда даже когда именуем каждую переменную по отдельности, получится очень грязно и избыточно (но это тот случай, когда обычно явно лучше, чем неявное).
Пример 1
Следующая функция описывает, как их можно использовать, и демонстрирует поведение. Обратите внимание, что именованный
b
аргумент будет использован вторым позиционным аргументом перед:Мы можем проверить онлайн-справку для подписи функции, с
help(foo)
которой говорит намДавайте назовем эту функцию с
foo(1, 2, 3, 4, e=5, f=6, g=7)
который печатает:
Пример 2
Мы также можем вызвать его с помощью другой функции, в которую мы просто добавляем
a
:bar(100)
печатает:Пример 3: практическое использование в декораторах
Хорошо, возможно, мы еще не увидели утилиту. Итак, представьте, что у вас есть несколько функций с избыточным кодом до и / или после дифференцирующего кода. Следующие именованные функции являются просто псевдокодом для иллюстративных целей.
Мы могли бы справиться с этим по-другому, но мы, безусловно, можем извлечь избыточность с помощью декоратора, и поэтому наш пример ниже демонстрирует, как
*args
и**kwargs
может быть очень полезным:И теперь каждая упакованная функция может быть написана гораздо более кратко, поскольку мы учли избыточность:
А благодаря выделению нашего кода, что
*args
и**kwargs
позволяет нам это сделать, мы сокращаем количество строк кода, улучшаем удобочитаемость и удобство обслуживания, а также имеем единственные канонические места для логики в нашей программе. Если нам нужно изменить какую-либо часть этой структуры, у нас есть одно место для каждого изменения.источник
Давайте сначала разберемся, что такое позиционные аргументы и ключевые аргументы. Ниже приведен пример определения функции с позиционными аргументами.
Так что это определение функции с позиционными аргументами. Вы также можете вызвать его с помощью ключевых слов / именованных аргументов:
Теперь давайте изучим пример определения функции с ключевыми словами :
Вы также можете вызвать эту функцию с позиционными аргументами:
Итак, теперь мы знаем определения функций как с позиционными, так и с ключевыми словами.
Теперь давайте изучим оператор '*' и оператор **.
Обратите внимание, что эти операторы могут быть использованы в 2 областях:
а) вызов функции
б) определение функции
Использование оператора «*» и оператора «**» в вызове функции.
Давайте перейдем непосредственно к примеру и обсудим его.
Так что помни
когда оператор '*' или '**' используется в вызове функции -
Оператор '*' распаковывает структуру данных, такую как список или кортеж, в аргументы, необходимые для определения функции.
Оператор '**' распаковывает словарь в аргументы, необходимые для определения функции.
Теперь давайте изучим использование оператора '*' в определении функции . Пример:
В определении функции оператор '*' упаковывает полученные аргументы в кортеж.
Теперь давайте рассмотрим пример «**», используемого в определении функции:
В определении функции Оператор '**' упаковывает полученные аргументы в словарь.
Итак, помните:
При вызове функции распаковка '*' структуру данных кортежа или списка в позиционные или ключевые аргументы, которые должны быть получены определением функции.
При вызове функции «**» распаковывает структуру данных словаря в позиционные или ключевые аргументы, которые должны быть получены определением функции.
В определении функции '*' упаковывает позиционные аргументы в кортеж.
В определении функции «**» упаковывает аргументы ключевых слов в словарь.
источник
Эта таблица удобна для использования
*
и**
при построении функций, и при вызове функций :Это действительно просто, чтобы подвести итог ответа Лорин Хохштайн, но я считаю его полезным.
В связи с этим: использование для операторов star / splat было расширено в Python 3
источник
*
и**
имеют специальное использование в списке аргументов функции.*
подразумевает, что аргумент является списком и**
подразумевает, что аргумент является словарем. Это позволяет функциям принимать произвольное количество аргументовисточник
Для тех из вас, кто учится на примерах!
*
состоит в том, чтобы дать вам возможность определить функцию, которая может принимать произвольное количество аргументов, представленных в виде списка (например,f(*myList)
).**
состоит в том, чтобы дать вам возможность передать аргументы функции, предоставив словарь (напримерf(**{'x' : 1, 'y' : 2})
).Покажем это, определив функцию , которая принимает два нормальных переменных
x
,y
и может принять больше аргументов , какmyArgs
, и может принять еще больше аргументов , какmyKW
. Позже мы покажем, как кормитьy
с помощьюmyArgDict
.Предостережения
**
исключительно зарезервировано для словарей.**
должен прийти после*
, всегда.источник
Из документации Python:
источник
*
означает получить переменные аргументы как кортеж**
означает получать переменные аргументы как словарьИспользуется как следующее:
1) одиночный *
Вывод:
2) Сейчас
**
Вывод:
источник
Я хочу привести пример, который другие не упомянули
* также можно распаковать генератор
Пример из Документа Python3
unzip_x будет [1, 2, 3], unzip_y будет [4, 5, 6]
Zip () получает несколько аргументов iretable и возвращает генератор.
источник
В Python 3.5, вы также можете использовать этот синтаксис
list
,dict
,tuple
иset
дисплеи (также иногда называемые литералов). См. PEP 488: Дополнительные обобщения распаковки .Это также позволяет распаковывать несколько итераций за один вызов функции.
(Спасибо mgilson за ссылку PEP.)
источник
В дополнение к вызовам функций * args и ** kwargs полезны в иерархиях классов, а также избегают необходимости писать
__init__
метод в Python. Подобное использование можно увидеть в таких фреймворках, как код Django.Например,
Подкласс может быть
Подкласс затем будет создан как
Кроме того, подкласс с новым атрибутом, который имеет смысл только для этого экземпляра подкласса, может вызывать базовый класс
__init__
для разгрузки настройки атрибутов. Это делается с помощью * args и ** kwargs. kwargs в основном используется для того, чтобы код читался с использованием именованных аргументов. Например,которые могут быть установлены как
Полный код здесь
источник
Опираясь на ответ Никда ...
Вывод:
По сути, любое количество позиционных аргументов может использовать * args, а любые именованные аргументы (или аргументы ключевого слова kwargs или aka) могут использовать ** kwargs.
источник
*args
и**kwargs
: позволяют передавать переменное число аргументов функции.*args
: используется для отправки списка аргументов переменной длины без ключа в функцию:Будет производить:
**kwargs*
**kwargs
позволяет передавать ключевую переменную длины аргументов в функцию. Вы должны использовать,**kwargs
если вы хотите обрабатывать именованные аргументы в функции.Будет производить:
источник
Этот пример поможет вам вспомнить
*args
,**kwargs
и дажеsuper
и наследование в Python сразу.источник
Хороший пример использования обоих в функции:
источник
TL; DR
Ниже приведены 6 различных вариантов использования для
*
и**
в питона программирования:*args
:,def foo(*args): pass
здесьfoo
принимает любое количество позиционных аргументов, т.е. допустимы следующие вызовыfoo(1)
,foo(1, 'bar')
**kwargs
:,def foo(**kwargs): pass
здесь 'foo' принимает любое количество аргументов ключевого слова, т. Е. Допустимы следующие вызовыfoo(name='Tom')
,foo(name='Tom', age=33)
*args, **kwargs
:,def foo(*args, **kwargs): pass
здесьfoo
принимает любое количество позиционных и ключевых аргументов, т.е. допустимы следующие вызовыfoo(1,name='Tom')
,foo(1, 'bar', name='Tom', age=33)
*
:,def foo(pos1, pos2, *, kwarg1): pass
здесь*
означает, что foo принимает аргументы только из ключевых слов после pos2, следовательно,foo(1, 2, 3)
вызывает TypeError, ноfoo(1, 2, kwarg1=3)
это нормально.*_
(Примечание: это только соглашение):def foo(bar, baz, *_): pass
означает (по соглашению)foo
только использованиеbar
иbaz
аргументы в своей работе и игнорирование других.\**_
(Примечание: это только соглашение):def foo(bar, baz, **_): pass
означает (по соглашению)foo
только использованиеbar
иbaz
аргументы в своей работе и игнорирование других.БОНУС: Начиная с Python 3.8, можно использовать
/
в определении функции для обеспечения только позиционных параметров. В следующем примере параметры a и b являются только позиционными , в то время как c или d могут быть позиционными или ключевыми словами, а e или f должны быть ключевыми словами:источник
TL; DR
Он упаковывает аргументы, переданные функции, в тело функции
list
и,dict
соответственно, внутри него. Когда вы определяете сигнатуру функции следующим образом:он может быть вызван с любым количеством аргументов и аргументов ключевого слова. Аргументы без ключевых слов упаковываются в список, вызываемый
args
внутри тела функции, а аргументы с ключевыми словами упаковываются в dict, вызываемыйkwds
внутри тела функции.Теперь внутри тела функции, когда функция вызывается, есть две локальные переменные,
args
которая представляет собой список , имеющий значение["this", "is a list of", "non-keyword", "arguments"]
иkwds
который представляет собойdict
имеющее значение{"keyword" : "ligma", "options" : [1,2,3]}
Это также работает в обратном порядке, то есть со стороны вызывающего абонента. например, если у вас есть функция, определенная как:
Вы можете вызвать его, распаковав итерации или сопоставления, которые есть в области вызова:
источник
контекст
**
Использовать с форматированием строки
В дополнение к ответам в этой теме, здесь есть еще одна деталь, которая не упоминалась где-либо еще. Это расширяет ответ Брэда Соломона
Распаковка с помощью
**
также полезна при использовании pythonstr.format
.Это несколько похоже на то, что вы можете сделать с Python
f-strings
F-строки но с дополнительными накладными расходами объявления объявления для хранения переменных (f-строка не требует dict).Быстрый пример
источник
def foo(param1, *param2):
метод может принимать произвольное количество значений для*param2
,def bar(param1, **param2):
метод может принимать произвольное количество значений с ключами для*param2
param1
это простой параметр.Например, синтаксис для реализации varargs в Java выглядит следующим образом:
источник