web-dev-qa-db-ja.com

* argsと** kwargsの使用

だから私は*args**kwargsの概念に困難があります。

これまでのところ、私は以下のことを学びました。

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

これがどのようなプログラミング作業に役立つのか理解できません。

多分:

リストや辞書を関数の引数として、ワイルドカードと同時に入力することを考えていますが、どのような引数でも渡すことができますか?

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

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

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

1301
MacPython

構文は*および** です。 *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

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

1574
Dave Webb

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

464
Mark van Lent

これは、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}
301
Kit

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

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

名前そのものを使用するのに比べて、それが非常に速いかどうかはわかりませんが、入力ははるかに簡単です。

69
Wayne Werner

* 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
43
jchl

* 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が印刷されます。

35
Steven Mohr

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

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

それから、あなたはこのような関数を使います:

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

or

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

*args**kwargsまたは**kwという名前は純粋に慣例によるものです。お互いのコードを読みやすくなります。

便利なのは、structモジュールを使うときです。

struct.unpack()はTupleを返しますが、struct.pack()は可変数の引数を使用します。データを操作するときは、Tupleを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が変更されてTupleのサイズが変更された場合にも、戻って編集する必要があります

16
John La Rooy

* args/** kwargsは関数呼び出し構文の一部であり、実際には演算子ではありません。これは私が遭遇した特定の副作用を持ちます、それはあなたがprint文で* args展開を使うことができないということです、なぜならprintは関数ではないからです。

これは妥当と思われます。

def myprint(*args):
    print *args

残念ながらコンパイルできません(構文エラー)。

これはコンパイルします:

def myprint(*args):
    print args

しかし、引数をタプルとして出力しますが、これは私たちが望むことではありません。

これが私が決めた解決策です。

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

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

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

しかし、これらのパラメータは実際のパラメータ名を隠すので、それらを避けるのが良いです。

7
Rudi

Pythonドキュメント(FAQのdocs.python.org)を見ることもできますが、より具体的には ミステリアスなミス引数とmister kwargs(archive.orgの好意による) (原文、デッドリンクは ここ )です。

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

myfunction(myarg=1)
3
Yoni H