だから私は*args
と**kwargs
の概念に困難があります。
これまでのところ、私は以下のことを学びました。
*args
=引数のリスト - 位置引数として**kwargs
= dictionary - そのキーは別々のキーワード引数になり、値はこれらの引数の値になります。これがどのようなプログラミング作業に役立つのか理解できません。
多分:
リストや辞書を関数の引数として、ワイルドカードと同時に入力することを考えていますが、どのような引数でも渡すことができますか?
*args
と**kwargs
の使い方を説明する簡単な例はありますか?
また、私が見つけたチュートリアルでは "*"と変数名だけを使いました。
*args
と**kwargs
は単なるプレースホルダーですか、それともコード内で正確に*args
と**kwargs
を使用しますか?
構文は*
および**
です。 *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
あなたがこの場合見ることができるようにそれはアイテムのリスト(またはタプル)を取り、それを開梱します。これにより、それらは関数内の引数と一致します。もちろん、関数定義と関数呼び出しの両方に*
を含めることができます。
*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クラスに渡すだけです。
これは、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}
Dave Webbの最後の例のように、**
構文を使用するのが私のお気に入りの場所の1つです。
mynum = 1000
mystr = 'Hello World!'
print "{mystr} New-style formatting is {mynum}x more fun!".format(**locals())
名前そのものを使用するのに比べて、それが非常に速いかどうかはわかりませんが、入力ははるかに簡単です。
* 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
* 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が印刷されます。
あなたが関数を持っていると想像してみてください、しかしあなたはそれが取るパラメータの数を制限したくありません。例:
>>> import operator
>>> def multiply(*args):
... return reduce(operator.mul, args)
それから、あなたはこのような関数を使います:
>>> multiply(1,2,3)
6
or
>>> numbers = [1,2,3]
>>> multiply(*numbers)
6
*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のサイズが変更された場合にも、戻って編集する必要があります
* 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
これらのパラメータは通常プロキシ機能に使用されるため、プロキシは任意の入力パラメータをターゲット機能に渡すことができます。
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
しかし、これらのパラメータは実際のパラメータ名を隠すので、それらを避けるのが良いです。
Pythonドキュメント(FAQのdocs.python.org)を見ることもできますが、より具体的には ミステリアスなミス引数とmister kwargs(archive.orgの好意による) (原文、デッドリンクは ここ )です。
一言で言えば、両方とも関数またはメソッドへのオプションのパラメータが使用されるときに使用されます。 Daveが言っているように、引数がいくつ渡されるかわからないときは* argsが、名前と値で指定されたパラメータを処理したいときは** kwargsが使われます。
myfunction(myarg=1)