使用* args和** kwargs [重复]

时间:2022-02-02 21:21:59

This question already has an answer here:

这个问题在这里已有答案:

So I have difficulty with the concept of *args and **kwargs.

所以我对* args和** kwargs的概念有困难。

So far I have learned that:

到目前为止,我已经了解到:

  • *args = list of arguments - as positional arguments
  • * args =参数列表 - 作为位置参数

  • **kwargs = dictionary - whose keys become separate keyword arguments and the values become values of these arguments.
  • ** kwargs = dictionary - 其键成为单独的关键字参数,值成为这些参数的值。

I don't understand what programming task this would be helpful for.

我不明白这会对哪些编程任务有所帮助。

Maybe:

I think to enter lists and dictionaries as arguments of a function AND at the same time as a wildcard, so I can pass ANY argument?

我想输入列表和字典作为函数AND的参数同时作为通配符,所以我可以传递任何参数?

Is there a simple example to explain how *args and **kwargs are used?

是否有一个简单的例子来解释如何使用* args和** kwargs?

Also the tutorial I found used just the "*" and a variable name.

我发现的教程也使用了“*”和变量名。

Are *args and **kwargs just placeholders or do you use exactly *args and **kwargs in the code?

* args和** kwargs只是占位符还是在代码中使用* args和** kwargs?

11 个解决方案

#1


The syntax is the * and **. The names *args and **kwargs are only by convention but there's no hard requirement to use them.

语法是*和**。名称* args和** kwargs仅按惯例,但没有硬性要求使用它们。

You would use *args when you're not sure how many arguments might be passed to your function, i.e. it allows you pass an arbitrary number of arguments to your function. For example:

当您不确定可以向您的函数传递多少个参数时,您将使用* args,即它允许您向函数传递任意数量的参数。例如:

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

Similarly, **kwargs allows you to handle named arguments that you have not defined in advance:

类似地,** kwargs允许您处理未事先定义的命名参数:

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

You can use these along with named arguments too. The explicit arguments get values first and then everything else is passed to *args and **kwargs. The named arguments come first in the list. For example:

您也可以将这些与命名参数一起使用。显式参数首先获取值,然后将其他所有内容传递给* args和** kwargs。命名参数在列表中排在第一位。例如:

def table_things(titlestring, **kwargs)

You can also use both in the same function definition but *args must occur before **kwargs.

您也可以在同一个函数定义中使用它们,但* args必须在** kwargs之前出现。

You can also use the * and ** syntax when calling a function. For example:

调用函数时,您还可以使用*和**语法。例如:

>>> 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

As you can see in this case it takes the list (or tuple) of items and unpacks it. By this it matches them to the arguments in the function. Of course, you could have a * both in the function definition and in the function call.

正如您在本案中所看到的,它会获取项目的列表(或元组)并将其解包。通过这个它将它们与函数中的参数匹配。当然,你可以在函数定义和函数调用中都有*。

#2


One place where the use of *args and **kwargs is quite useful is for subclassing.

使用* args和** kwargs非常有用的一个地方是子类化。

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

This way you can extend the behaviour of the Foo class, without having to know too much about Foo. This can be quite convenient if you are programming to an API which might change. MyFoo just passes all arguments to the Foo class.

这样你就可以扩展Foo类的行为,而不必过多地了解Foo。如果您正在编程可能会更改的API,这可能非常方便。 MyFoo只是将所有参数传递给Foo类。

#3


Here's an example that uses 3 different types of parameters.

这是一个使用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


Here's one of my favorite places to use the ** syntax as in Dave Webb's final example:

这是我最喜欢使用**语法的地方之一,如Dave Webb的最后一个例子:

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

I'm not sure if it's terribly fast when compared to just using the names themselves, but it's a lot easier to type!

与仅使用名称本身相比,我不确定它是否非常快,但输入起来要容易得多!

#5


One case where *args and **kwargs are useful is when writing wrapper functions (such as decorators) that need to be able accept arbitrary arguments to pass through to the function being wrapped. For example, a simple decorator that prints the arguments and return value of the function being wrapped:

* args和** kwargs有用的一种情况是编写包装器函数(例如装饰器)时需要能够接受任意参数传递给被包装的函数。例如,一个简单的装饰器打印参数并返回被包装函数的值:

def mydecorator( f ):   @functools.wraps( f )   def wrapper( *args, **kwargs ):      print "Calling f", args, kwargs      v = f( *args, **kwargs )      print "f returned", v      return v   return wrapper

#6


*args and **kwargs are special-magic features of Python.Think of a function that could have an unknown number of arguments. For example, for whatever reasons, you want to have function that sums an unknown number of numbers (and you don't want to use the built-in sum function). So you write this function:

* args和** kwargs是Python的特殊魔术特性。可以包含未知数量的参数的函数。例如,无论出于何种原因,您希望具有对未知数量的数字求和的函数(并且您不想使用内置求和函数)。所以你写这个函数:

def sumFunction(*args):  result = 0  for x in args:    result += x  return result

and use it like: sumFunction(3,4,6,3,6,8,9).

并使用它:sumFunction(3,4,6,3,6,8,9)。

**kwargs has a diffrent function. With **kwargs you can give arbitrary keyword arguments to a function and you can access them as a dictonary.

** kwargs具有不同的功能。使用** kwargs,您可以为函数提供任意关键字参数,并且可以作为dictonary访问它们。

def someFunction(**kwargs):  if 'text' in kwargs:    print kwargs['text']

Calling someFunction(text="foo") will print foo.

调用someFunction(text =“foo”)将打印foo。

#7


Just imagine you have a function but you don't want to restrict the number of parameter it takes.Example:

想象一下你有一个函数,但你不想限制它所参数的数量。例如:

>>> import operator>>> def multiply(*args):...  return reduce(operator.mul, args)

Then you use this function like:

然后你使用这个函数,如:

>>> multiply(1,2,3)6or>>> numbers = [1,2,3]>>> multiply(*numbers)6

#8


The names *args and **kwargs or **kw are purely by convention. It makes it easier for us to read each other's code

名称* args和** kwargs或** kw纯粹是按照惯例。它使我们更容易阅读彼此的代码

One place it is handy is when using the struct module

一个方便的地方是使用struct模块

struct.unpack() returns a tuple whereas struct.pack() uses a variable number of arguments. When manipulating data it is convenient to be able to pass a tuple to struck.pack() eg.

struct.unpack()返回一个元组,而struct.pack()使用可变数量的参数。在操作数据时,能够将元组传递给struck.pack()是很方便的。

tuple_of_data = struct.unpack(format_str, data)... manipulate the datanew_data = struct.pack(format_str, *tuple_of_data)

without this ability you would be forced to write

如果没有这种能力,你将*写作

new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)

which also means the if the format_str changes and the size of the tuple changes, I'll have to go back and edit that really long line

这也意味着如果format_str改变并且元组的大小发生变化,我将不得不返回并编辑那个很长的行

#9


Note that *args/**kwargs is part of function-calling syntax, and not really an operator. This has a particular side effect that I ran into, which is that you can't use *args expansion with the print statement, since print is not a function.

请注意,* args / ** kwargs是函数调用语法的一部分,而不是真正的运算符。这有一个特殊的副作用,我遇到了,你不能使用* args扩展与print语句,因为print不是一个函数。

This seems reasonable:

这似乎是合理的:

def myprint(*args):    print *args

Unfortunately it doesn't compile (syntax error).

不幸的是它没有编译(语法错误)。

This compiles:

def myprint(*args):    print args

But prints the arguments as a tuple, which isn't what we want.

但是将参数打印为元组,这不是我们想要的。

This is the solution I settled on:

这是我解决的解决方案:

def myprint(*args):    for arg in args:        print arg,    print

#10


These parameters are typically used for proxy functions, so the proxy can pass any input parameter to the target function.

这些参数通常用于代理函数,因此代理可以将任何输入参数传递给目标函数。

def foo(bar=2, baz=5):    print bar, bazdef proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments    print x    foo(*args, **kwargs) # applies the "non-x" parameter to fooproxy(23, 5, baz='foo') # calls foo with bar=5 and baz=fooproxy(6)# calls foo with its default argumentsproxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

But since these parameters hide the actual parameter names, it is better to avoid them.

但由于这些参数隐藏了实际的参数名称,因此最好避免使用它们。

#11


You can have a look at python docs (docs.python.org in the FAQ), but more specifically for a good explanation the mysterious miss args and mister kwargs (courtesy of archive.org) (the original, dead link is here).

您可以查看python docs(FAQ中的docs.python.org),但更具体地说是一个很好的解释,神秘的miss args和mister kwargs(由archive.org提供)(原始的,死链接在这里)。

In a nutshell, both are used when optional parameters to a function or method are used. As Dave says, *args is used when you don't know how many arguments may be passed, and **kwargs when you want to handle parameters specified by name and value as in:

简而言之,当使用函数或方法的可选参数时,都使用它们。正如Dave所说,当你不知道可以传递多少个参数时会使用* args,而当你想要处理name和value指定的参数时会使用** kwargs,如:

myfunction(myarg=1)

#1


The syntax is the * and **. The names *args and **kwargs are only by convention but there's no hard requirement to use them.

语法是*和**。名称* args和** kwargs仅按惯例,但没有硬性要求使用它们。

You would use *args when you're not sure how many arguments might be passed to your function, i.e. it allows you pass an arbitrary number of arguments to your function. For example:

当您不确定可以向您的函数传递多少个参数时,您将使用* args,即它允许您向函数传递任意数量的参数。例如:

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

Similarly, **kwargs allows you to handle named arguments that you have not defined in advance:

类似地,** kwargs允许您处理未事先定义的命名参数:

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

You can use these along with named arguments too. The explicit arguments get values first and then everything else is passed to *args and **kwargs. The named arguments come first in the list. For example:

您也可以将这些与命名参数一起使用。显式参数首先获取值,然后将其他所有内容传递给* args和** kwargs。命名参数在列表中排在第一位。例如:

def table_things(titlestring, **kwargs)

You can also use both in the same function definition but *args must occur before **kwargs.

您也可以在同一个函数定义中使用它们,但* args必须在** kwargs之前出现。

You can also use the * and ** syntax when calling a function. For example:

调用函数时,您还可以使用*和**语法。例如:

>>> 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

As you can see in this case it takes the list (or tuple) of items and unpacks it. By this it matches them to the arguments in the function. Of course, you could have a * both in the function definition and in the function call.

正如您在本案中所看到的,它会获取项目的列表(或元组)并将其解包。通过这个它将它们与函数中的参数匹配。当然,你可以在函数定义和函数调用中都有*。

#2


One place where the use of *args and **kwargs is quite useful is for subclassing.

使用* args和** kwargs非常有用的一个地方是子类化。

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

This way you can extend the behaviour of the Foo class, without having to know too much about Foo. This can be quite convenient if you are programming to an API which might change. MyFoo just passes all arguments to the Foo class.

这样你就可以扩展Foo类的行为,而不必过多地了解Foo。如果您正在编程可能会更改的API,这可能非常方便。 MyFoo只是将所有参数传递给Foo类。

#3


Here's an example that uses 3 different types of parameters.

这是一个使用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


Here's one of my favorite places to use the ** syntax as in Dave Webb's final example:

这是我最喜欢使用**语法的地方之一,如Dave Webb的最后一个例子:

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

I'm not sure if it's terribly fast when compared to just using the names themselves, but it's a lot easier to type!

与仅使用名称本身相比,我不确定它是否非常快,但输入起来要容易得多!

#5


One case where *args and **kwargs are useful is when writing wrapper functions (such as decorators) that need to be able accept arbitrary arguments to pass through to the function being wrapped. For example, a simple decorator that prints the arguments and return value of the function being wrapped:

* args和** kwargs有用的一种情况是编写包装器函数(例如装饰器)时需要能够接受任意参数传递给被包装的函数。例如,一个简单的装饰器打印参数并返回被包装函数的值:

def mydecorator( f ):   @functools.wraps( f )   def wrapper( *args, **kwargs ):      print "Calling f", args, kwargs      v = f( *args, **kwargs )      print "f returned", v      return v   return wrapper

#6


*args and **kwargs are special-magic features of Python.Think of a function that could have an unknown number of arguments. For example, for whatever reasons, you want to have function that sums an unknown number of numbers (and you don't want to use the built-in sum function). So you write this function:

* args和** kwargs是Python的特殊魔术特性。可以包含未知数量的参数的函数。例如,无论出于何种原因,您希望具有对未知数量的数字求和的函数(并且您不想使用内置求和函数)。所以你写这个函数:

def sumFunction(*args):  result = 0  for x in args:    result += x  return result

and use it like: sumFunction(3,4,6,3,6,8,9).

并使用它:sumFunction(3,4,6,3,6,8,9)。

**kwargs has a diffrent function. With **kwargs you can give arbitrary keyword arguments to a function and you can access them as a dictonary.

** kwargs具有不同的功能。使用** kwargs,您可以为函数提供任意关键字参数,并且可以作为dictonary访问它们。

def someFunction(**kwargs):  if 'text' in kwargs:    print kwargs['text']

Calling someFunction(text="foo") will print foo.

调用someFunction(text =“foo”)将打印foo。

#7


Just imagine you have a function but you don't want to restrict the number of parameter it takes.Example:

想象一下你有一个函数,但你不想限制它所参数的数量。例如:

>>> import operator>>> def multiply(*args):...  return reduce(operator.mul, args)

Then you use this function like:

然后你使用这个函数,如:

>>> multiply(1,2,3)6or>>> numbers = [1,2,3]>>> multiply(*numbers)6

#8


The names *args and **kwargs or **kw are purely by convention. It makes it easier for us to read each other's code

名称* args和** kwargs或** kw纯粹是按照惯例。它使我们更容易阅读彼此的代码

One place it is handy is when using the struct module

一个方便的地方是使用struct模块

struct.unpack() returns a tuple whereas struct.pack() uses a variable number of arguments. When manipulating data it is convenient to be able to pass a tuple to struck.pack() eg.

struct.unpack()返回一个元组,而struct.pack()使用可变数量的参数。在操作数据时,能够将元组传递给struck.pack()是很方便的。

tuple_of_data = struct.unpack(format_str, data)... manipulate the datanew_data = struct.pack(format_str, *tuple_of_data)

without this ability you would be forced to write

如果没有这种能力,你将*写作

new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)

which also means the if the format_str changes and the size of the tuple changes, I'll have to go back and edit that really long line

这也意味着如果format_str改变并且元组的大小发生变化,我将不得不返回并编辑那个很长的行

#9


Note that *args/**kwargs is part of function-calling syntax, and not really an operator. This has a particular side effect that I ran into, which is that you can't use *args expansion with the print statement, since print is not a function.

请注意,* args / ** kwargs是函数调用语法的一部分,而不是真正的运算符。这有一个特殊的副作用,我遇到了,你不能使用* args扩展与print语句,因为print不是一个函数。

This seems reasonable:

这似乎是合理的:

def myprint(*args):    print *args

Unfortunately it doesn't compile (syntax error).

不幸的是它没有编译(语法错误)。

This compiles:

def myprint(*args):    print args

But prints the arguments as a tuple, which isn't what we want.

但是将参数打印为元组,这不是我们想要的。

This is the solution I settled on:

这是我解决的解决方案:

def myprint(*args):    for arg in args:        print arg,    print

#10


These parameters are typically used for proxy functions, so the proxy can pass any input parameter to the target function.

这些参数通常用于代理函数,因此代理可以将任何输入参数传递给目标函数。

def foo(bar=2, baz=5):    print bar, bazdef proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments    print x    foo(*args, **kwargs) # applies the "non-x" parameter to fooproxy(23, 5, baz='foo') # calls foo with bar=5 and baz=fooproxy(6)# calls foo with its default argumentsproxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

But since these parameters hide the actual parameter names, it is better to avoid them.

但由于这些参数隐藏了实际的参数名称,因此最好避免使用它们。

#11


You can have a look at python docs (docs.python.org in the FAQ), but more specifically for a good explanation the mysterious miss args and mister kwargs (courtesy of archive.org) (the original, dead link is here).

您可以查看python docs(FAQ中的docs.python.org),但更具体地说是一个很好的解释,神秘的miss args和mister kwargs(由archive.org提供)(原始的,死链接在这里)。

In a nutshell, both are used when optional parameters to a function or method are used. As Dave says, *args is used when you don't know how many arguments may be passed, and **kwargs when you want to handle parameters specified by name and value as in:

简而言之,当使用函数或方法的可选参数时,都使用它们。正如Dave所说,当你不知道可以传递多少个参数时会使用* args,而当你想要处理name和value指定的参数时会使用** kwargs,如:

myfunction(myarg=1)