web-dev-qa-db-ja.com

関数の引数に裸のアスタリスクがありますか?

関数の引数の中の裸のアスタリスクは何をしますか?

pickle module を見ると、次のように見えます:

pickle.dump(obj, file, protocol=None, *, fix_imports=True)

引数の前に1つと2つのアスタリスクがあることは知っています(可変数の引数の場合)が、これは何にも先行していません。そして、これはピクルスとは何の関係もないと確信しています。それはおそらくこの出来事の単なる例です。通訳にこれを送ったとき、私はその名前を知っただけです:

>>> def func(*):
...     pass
...
  File "<stdin>", line 1
SyntaxError: named arguments must follow bare *

問題があれば、python 3.3.0。

194
Eric

Bare *は、呼び出し側に名前付き引数を使用させるために使用されます。したがって、次のキーワード引数がない場合、*を引数として関数を定義することはできません。

詳細については、 この回答 または Python 3ドキュメント を参照してください。

185
Kimvais

元の回答は質問に完全に回答しますが、関連情報を少し追加するだけです。単一のアスタリスクの動作は、 PEP-3102 に由来します。関連セクションの引用:

The second syntactical change is to allow the argument name to
be omitted for a varargs argument. The meaning of this is to
allow for keyword-only arguments for functions that would not
otherwise take a varargs argument:

    def compare(a, b, *, key=None):
        ...

簡単な英語では、キーの値を渡すには、key="value"として明示的に渡す必要があることを意味します。

60
mu 無
def func(*, a, b):
    print(a)
    print(b)

func("gg") # TypeError: func() takes 0 positional arguments but 1 was given
func(a="gg") # TypeError: func() missing 1 required keyword-only argument: 'b'
func(a="aa", b="bb", c="cc") # TypeError: func() got an unexpected keyword argument 'c'
func(a="aa", b="bb", "cc") # SyntaxError: positional argument follows keyword argument
func(a="aa", b="bb") # aa, bb

** kwargsを使用した上記の例

def func(*, a, b, **kwargs):
    print(a)
    print(b)
    print(kwargs)

func(a="aa",b="bb", c="cc") # aa, bb, {'c': 'cc'}
10
laycat

次のリンクは、**args、および**kwargsの説明に非常に役立つことがわかりました。

https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/

基本的に、上記の回答に加えて、上記のサイトから次のことを学びました(クレジット: https://pythontips.com/author/yasoob008/ )。

以下に最初に定義されたデモンストレーション関数では、*args**kwargsの2つの例があります。

def test_args_kwargs(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

# first with *args
>>> args = ("two", 3,5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5

# now with **kwargs:
>>> kwargs = {"arg3": 3, "arg2": "two","arg1":5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3

したがって、*argsを使用すると、引数の供給順に取得される引数のリストを動的に作成できます。一方、**kwargsを使用すると、NAMED引数を渡すことができ、NAMEによって適切に処理できます(それらが供給される順序に関係なく)。

引数の正しい順序は次のとおりであることに注意して、サイトは続行します。

some_func(fargs,*args,**kwargs)
1
lb_so