使用 *args 和 **kwargs

发布于 2024-09-12 10:05:22 字数 451 浏览 8 评论 0原文

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

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

  • *args = 参数列表 - 作为位置参数
  • **kwargs = 字典 - 其键成为单独的关键字参数,值成为这些参数的值论据。

我不明白这对什么编程任务有帮助。

也许:

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

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

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

*args**kwargs 只是占位符,还是您在代码?

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

So far I have learned that:

  • *args = list of arguments - as positional arguments
  • **kwargs = dictionary - whose keys become separate keyword arguments and the values become values of these arguments.

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?

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

你是我的挚爱i 2024-09-19 10:05:22

语法是 ** *。名称 *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

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

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

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:

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

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

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

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:

def table_things(titlestring, **kwargs)

You can also use both in the same function definition but *args must occur before **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.

你不是我要的菜∠ 2024-09-19 10:05:22

使用 *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 类。

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

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)

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.

半城柳色半声笛 2024-09-19 10:05:22

下面是一个使用 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}

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

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}
终止放荡 2024-09-19 10:05:22

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

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

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

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

mynum = 1000
mystr = '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!

月光色 2024-09-19 10:05:22

*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

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:

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
芸娘子的小脾气 2024-09-19 10:05:22

*args 和 **kwargs 是 Python 的特殊神奇功能。
想象一个可能有未知数量参数的函数。例如,无论出于何种原因,您希望拥有对未知数量的数字求和的函数(并且您不想使用内置的 sum 函数)。所以你编写这个函数:

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

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

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

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

调用 someFunction(text="foo") 将打印 foo.

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

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

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

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

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

最美的太阳 2024-09-19 10:05:22

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

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

然后您可以像这样使用这个函数:

>>> multiply(1,2,3)
6

or

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

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

or

>>> numbers = [1,2,3]
>>> multiply(*numbers)
6
两个我 2024-09-19 10:05:22

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

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

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

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

如果没有这种能力,您将被迫编写,

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

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

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

One place it is handy is when using the struct module

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.

tuple_of_data = struct.unpack(format_str, data)
# ... manipulate the data
new_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

朕就是辣么酷 2024-09-19 10:05:22

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

这似乎是合理的:

def myprint(*args):
    print *args

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

编译:

def myprint(*args):
    print args

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

这是我确定的解决方案:

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

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.

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
如果没有你 2024-09-19 10:05:22

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

def foo(bar=2, baz=5):
    print bar, baz

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

proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

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

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

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

proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(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.

莫言歌 2024-09-19 10:05:22

您可以查看 python 文档(常见问题解答中的 docs.python.org),但更具体地说是为了更好的解释 神秘的args小姐和kwargs先生(由archive.org提供)(原始的死链接是 此处)。

简而言之,当使用函数或方法的可选参数时,都会使用两者。
正如 Dave 所说,当您不知道可以传递多少个参数时,使用 *args;当您想要处理由名称和值指定的参数时,使用 **kwargs,如下所示:

myfunction(myarg=1)

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

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:

myfunction(myarg=1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文