関数の引数に裸のアスタリスク?


240

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

私が見たときpickleモジュール、私はこれを参照してください。

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を使用しています。


回答:


220

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

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


3
を含むすべての定位置(名前なし)引数は*args、bareの前になければならないことに注意してください*
BallpointBen 2017年

4
また、位置指定のみの引数の終わりを示す、対応する種類の/があることにも注意してください(stackoverflow.com/questions/28243832/…)。
スティーブン

2
@BallpointBen:はの*代わりに*args、その逆も同様です。署名には共存できません。それが彼らが選んだ理由*です。以前*argsは、純粋な位置引数を強制する唯一の方法であり、位置的に渡すことができる引数の終わりを示していました(残りのすべての位置引数を収集したため、次の名前付き引数に到達できました)。*同じ「位置引数はここを超えることはできません」を意味しますが、名前がないと「配置する場所を提供しないことを選択したため、まったく受け入れません」という意味です。
ShadowRanger

70

元の答えは質問に完全に答えますが、関連情報を少し追加するだけです。単一のアスタリスクの動作は、から派生してい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の値を渡すには、明示的にとして渡す必要がありますkey="value"


ああ、それは物事をより明確にします。したがって、実際には引数*は引数args *を持つようなものですが、名前を付けていないため、残りの引数を強制的にキーワードにするために、残りのすべての位置引数を静かに取得することが唯一の効果です。 -のみ。
スティーブン

11
@Stephen私も当初考えていましたが、bareの影響は*残りの位置引数を取り壊すことですが、そうではありません。:、この種のエラーを与える機能を期待よりも余分に位置引数を渡すfoo() takes exactly 1 positional argument (2 given)
アジャイM

18
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'}

5

意味的には、後続の引数がキーワードのみであることを意味するため、名前を指定せずに引数を指定しようとすると、エラーが発生します。例えば:

>>> def f(a, *, b):
...     return a + b
...
>>> f(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 1 positional argument but 2 were given
>>> f(1, b=2)
3

実用的には、キーワード引数を指定して関数を呼び出す必要があることを意味します。これは通常、引数の名前から与えられたヒントがないと、引数の目的を理解するのが難しいときに行われます。

たとえばsorted(nums, reverse=True)、書いsorted(nums, True)たかどうかを比較してください。後者は読みにくくなるため、Python開発者は前者の方法で記述させることにしました。


4

次のような機能があるとします。

def sum(a,key=5):
    return a + key 

この関数は2つの方法で呼び出すことができます。

sum(1,2) または sum(1,key=2)

sumキーワード引数のみを使用して関数を呼び出す必要があるとします。

*関数パラメーターリストに追加して、位置引数の終わりをマークします。

したがって、次のように定義された関数:

def sum(a,*,key=5):
    return a + key 

のみを使用して呼び出すことができます sum(1,key=2)


-1

私は次のリンクが非常に説明に役立つとわかりました**argsそして**kwargs

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

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

デモンストレーション関数が最初以下に定義すると、二つの例、を有するものがある*argsと、一方とは**kwargs

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)

2
この答えは質問とはほとんど関係ありません。機能を持たない古いpythonバージョンも使用しています。
Antti Haapala
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.