Вопрос-Ответ

Use of *args and **kwargs [duplicate]

Использование * args и ** kwargs

Итак, у меня трудности с концепцией *args и **kwargs.

До сих пор я узнал, что:


  • *args = список аргументов - в качестве позиционных аргументов

  • **kwargs = словарь - ключи которого становятся отдельными аргументами ключевого слова, а значения становятся значениями этих аргументов.

Я не понимаю, для какой задачи программирования это было бы полезно.

Возможно:

Я думаю ввести списки и словари в качестве аргументов функции И одновременно в качестве подстановочного знака, чтобы я мог передать ЛЮБОЙ аргумент?

Есть ли простой пример, объясняющий, как используются *args и **kwargs?

Также в найденном мной руководстве использовались только "*" и имя переменной.

Это *args и **kwargs просто заполнители или вы используете именно *args и **kwargs в коде?

Переведено автоматически
Ответ 1

Синтаксис - это * и **. Имена *args и **kwargs используются только по соглашению, но нет жестких требований к их использованию.

Вы бы использовали *args, когда не уверены, сколько аргументов может быть передано вашей функции, т. Е. Это позволяет вам передавать произвольное количество аргументов вашей функции. Например:

>>> def print_everything(*args):
for count, thing in enumerate(args):
... print( '{0}. {1}'.format(count, thing))
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage

Аналогично, **kwargs позволяет обрабатывать именованные аргументы, которые вы не определили заранее:

>>> def table_things(**kwargs):
... for name, value in kwargs.items():
... print( '{0} = {1}'.format(name, value))
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit

Вы также можете использовать их вместе с именованными аргументами. Сначала значения получают явные аргументы, а затем все остальное передается в *args и **kwargs. Именованные аргументы идут первыми в списке. Например:

def table_things(titlestring, **kwargs)

Вы также можете использовать оба варианта в одном определении функции, но *args они должны быть выполнены раньше **kwargs.

Вы также можете использовать синтаксис * и ** при вызове функции. Например:

>>> def print_three_things(a, b, c):
... print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat

Как вы можете видеть, в этом случае он принимает список (или кортеж) элементов и распаковывает его. При этом он сопоставляет их с аргументами в функции. Конечно, у вас может быть * как в определении функции, так и в вызове функции.

Ответ 2

Одно место, где использование *args и **kwargs весьма полезно, - это создание подклассов.

class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2

class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)

Таким образом, вы можете расширить поведение класса Foo, не зная слишком много о Foo . Это может быть довольно удобно, если вы программируете на API, который может измениться. myFoo просто передает все аргументы классу Foo .

Ответ 3

Вот пример, в котором используются 3 разных типа параметров.

def func(required_arg, *args, **kwargs):
# required_arg is a positional-only parameter.
print required_arg

# args is a tuple of positional arguments,
# because the parameter name has * prepended.
if args: # If args is not empty.
print args

# kwargs is a dictionary of keyword arguments,
# because the parameter name has ** prepended.
if kwargs: # If kwargs is not empty.
print kwargs

>>> func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() takes at least 1 argument (0 given)

>>> func("required argument")
required argument

>>> func("required argument", 1, 2, '3')
required argument
(1, 2, '3')

>>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
required argument
(1, 2, '3')
{'keyword2': 'foo', 'keyword1': 4}
Ответ 4

Вот одно из моих любимых мест для использования ** синтаксиса, как в последнем примере Дейва Уэбба:

mynum = 1000
mystr = 'Hello World!'
print("{mystr} New-style formatting is {mynum}x more fun!".format(**locals()))

Я не уверен, что это ужасно быстро по сравнению с простым использованием самих имен, но вводить его намного проще!

2023-07-03 13:23 python