1503

*argsだから私はとの概念に苦労してい**kwargsます。

これまでのところ、私はそれを学びました:

  • *args=引数のリスト-位置引数として
  • **kwargs=辞書-そのキーは個別のキーワード引数になり、値はこれらの引数の値になります。

これがどのプログラミングタスクに役立つかわかりません。

多分:

リストと辞書を関数の引数として、同時にワイルドカードとして入力すると思います。そのため、任意の引数を渡すことができますか?

*argsとの使用方法を説明する簡単な例はあり**kwargsますか?

また、私が見つけたチュートリアルでは、「*」と変数名だけを使用していました。

単なるプレースホルダーですか*args、それともコード内で**kwargs正確に使用*argsしていますか?**kwargs

4

11 に答える 11

1751

構文は*and**です。名前*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

この場合にわかるように、アイテムのリスト(またはタプル)を取得して解凍します。これにより、それらを関数の引数に一致させます。もちろん、*関数定義と関数呼び出しの両方に含めることができます。

于 2010-08-03T08:38:45.713 に答える
501

*argsとの使用**kwargsが非常に役立つ1つの場所は、サブクラス化です。

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クラスに渡すだけです。

于 2010-08-03T08:39:08.383 に答える
336

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}
于 2010-08-03T08:42:30.717 に答える
74

**以下は、Dave Webb の最後の例のように構文を使用する私のお気に入りの場所の 1 つです。

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

名前自体を使用する場合と比較して、非常に高速かどうかはわかりませんが、入力するのははるかに簡単です!

于 2010-08-03T13:03:49.660 に答える
49

*argsと**kwargsが役立つ1つのケースは、ラップされる関数に渡すために任意の引数を受け入れることができる必要があるラッパー関数(デコレーターなど)を作成する場合です。たとえば、ラップされている関数の引数と戻り値を出力する単純なデコレータは次のとおりです。

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
于 2010-08-03T08:40:34.930 に答える
42

*argsと**kwargsは、Pythonの特別な魔法の機能です。引数の数が不明な関数について考えてみてください。たとえば、何らかの理由で、不明な数の数値を合計する関数が必要です(そして、組み込みの合計関数を使用したくありません)。したがって、この関数を記述します。

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が出力されます。

于 2010-08-03T08:40:01.020 に答える
20

関数があるが、それが取るパラメーターの数を制限したくないと想像してみてください。例:

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

次に、次のようにこの関数を使用します。

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

or

>>> numbers = [1,2,3]
>>> multiply(*numbers)
6
于 2010-08-03T08:40:07.463 に答える
18

名前*args**kwargsまた**kwはは、単に慣習によるものです。お互いのコードを読みやすくする

便利な場所の 1 つは、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 が変更され、タプルのサイズが変更された場合、戻ってその非常に長い行を編集する必要があります。

于 2010-08-03T08:32:50.180 に答える
10

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
于 2010-11-10T21:07:46.080 に答える
8

これらのパラメーターは通常、プロキシ関数に使用されるため、プロキシは任意の入力パラメーターをターゲット関数に渡すことができます。

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

ただし、これらのパラメーターは実際のパラメーター名を隠してしまうため、避けたほうがよいでしょう。

于 2010-08-03T08:41:27.970 に答える
3

python docs(FAQのdocs.python.org)を見ることができますが、より具体的には、謎のミス引数とミスタークワーグ(archive.orgの提供)(元のデッドリンクはここにあります)。

一言で言えば、関数またはメソッドのオプションのパラメーターが使用される場合、両方が使用されます。Daveが言うように、渡される引数の数がわからない場合は* argsが使用され、名前と値で指定されたパラメーターを次のように処理する場合は**kwargsが使用されます。

myfunction(myarg=1)
于 2010-08-03T08:40:56.913 に答える