デフォルト以外の引数がデフォルトの引数に続くことができないのはなぜですか?


137

このコードがSyntaxErrorをスローするのはなぜですか?

  >>> def fun1(a="who is you", b="True", x, y):
...     print a,b,x,y
... 
  File "<stdin>", line 1
SyntaxError: non-default argument follows default argument

次のコードは目に見えるエラーなしで実行されますが、

>>> def fun1(x, y, a="who is you", b="True"):
...     print a,b,x,y
... 

Pythonでは、関数def myfunction(position_arguments, *arguments, **keywords):`....` を定義したときの構造です
abhishekgarg

回答:


172

すべての必須パラメーターは、デフォルトの引数の前に配置する必要があります。デフォルトの引数は必須ではないが、それらは必須であるためです。構文的には、混合モードが許可されている場合、インタープリターがどの値がどの引数に一致するかを決定することは不可能です。あSyntaxError引数が正しい順序で指定されていない場合は、が発生します。

関数を使用して、キーワード引数を見てみましょう。

def fun1(a="who is you", b="True", x, y):
...     print a,b,x,y

上記のように関数の宣言が許可されているとします。次に、上記の宣言を使用して、次の(通常の)位置またはキーワード引数を呼び出すことができます。

func1("ok a", "ok b", 1)  # Is 1 assigned to x or ?
func1(1)                  # Is 1 assigned to a or ?
func1(1, 2)               # ?

関数呼び出しでの変数の割り当てをどのように提案するか、デフォルト引数がキーワード引数とともにどのように使用されるか。

>>> def fun1(x, y, a="who is you", b="True"):
...     print a,b,x,y
... 

リファレンスO'Reilly-Core-Python
この関数はデフォルトの引数を使用するので、上記の関数呼び出しに対して構文的に正しい。キーワード引数呼び出しは、順序が狂った位置引数を提供できるので便利ですが、デフォルト引数と組み合わせることで、欠落している引数を「スキップ」することもできます。


4
<q>構文上、混合モードが許可されている場合、インタープリターがどの値がどの引数に一致するかを決定することは不可能です。</ q> Rubyは、デフォルトの引数に続くデフォルト以外の引数を許可します。<q>関数呼び出しでの変数の割り当てをどのように提案するか</ q>だけを使用しますfunc1(x=1, y=2)
2014

こんにちは@weakish、コメントに感謝します。Pythonにはこれを実現する良い方法があります。* argsと** kwargsを検索してください
Rahul Gautam

こんにちは@Rahul Gautam私は混乱しています。似たような作品**kwargsは作れないと思いましたdef fun1(a="who is you", b="True", x, y)。を使用する場合def f(**kwargs)、本体のデフォルト値を処理する必要がありますか?
2014

@weakish def fun1(a="who is you", b="True", x, y)は、同じことを異なるスタイルで実現できます。if def fun1(** kwrgs) ` fun1({'a': 'who is you', 'b': True})の場合、xとyを渡す必要はありません。
Rahul Gautam 2014

2
なぜ「構文的には、混合モードが許可されている場合、どの値がどの引数に一致するかをインタープリターが決定することは不可能です。」と書くのですか?PEP 3102のアルゴリズムは、たとえdef foo(x=None, y)許可されていても、まったく同じように機能すると思います。だから、なぜこれがPythonで許可されていないの、私はまだ興味があります。本当の根本的な理由はありますか、それとも「許可しないため許可しない」だけですか。
Jeroen Demeyer 2017

15
SyntaxError: non-default argument follows default argument

これを許可すると、デフォルト以外の引数がの後に来るため、デフォルト値を使用できなくなるため、デフォルト引数は役に立たなくなります。

ただし、Python 3では、次の操作を実行できます。

def fun1(a="who is you", b="True", *, x, y):
    pass

これはxyキーワードとなるため、これを行うことができます:

fun1(x=2, y=2)

これは、あいまいさがなくなるため機能します。それでもまだできないことに注意してくださいfun1(2, 2)(デフォルトの引数が設定されます)。


キーワードのみの引数はPython 3の優れた機能です。Python2.6と2.7にそれらをバックポートするパッチがあまりに悪かったため、期限が切れました
Nick Chammas

10

ここで2つのポイントを明確にしましょう:

  • 最初に、非デフォルト引数はデフォルト引数の後に続かないでください。つまり、関数で(a = b、c)を定義できないことを意味します。関数でパラメーターを定義する順序は次のとおりです。
    • 定位置パラメーターまたはデフォルト以外のパラメーター(a、b、c)
    • キーワードパラメータまたはデフォルトパラメータie(a = "b"、r = "j")
    • キーワードのみのパラメーターie(* args)
    • var-keywordパラメータie(** kwargs)

def example(a, b, c=None, r="w" , d=[], *ae, **ab):

(a、b)は位置パラメータです

(c = none)はオプションのパラメーターです

(r = "w")はキーワードパラメータです

(d = [])はリストパラメータです

(* ae)はキーワードのみです

(** ab)はvar-keywordパラメータです

  • 今二次的なことは私がこのようなことをしようとすると: def example(a, b, c=a,d=b):

デフォルト値が保存されるときに引数が定義されていない、関数を定義するときにPythonがデフォルト値を計算して保存する

これが発生した場合、cとdは定義されておらず、存在しません(関数の実行時にのみ存在します)。

"a、a = b"はパラメーターでは使用できません。


0

必要な引数(デフォルトのない引数)は、クライアントコードが2つだけを提供できるようにするために、最初にある必要があります。オプションの引数が最初にあった場合、混乱を招くでしょう:

fun1("who is who", 3, "jack")

あなたの最初の例ではそれは何をしますか?最後に、xは「誰が誰であるか」、yは3、a =「ジャック」です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.