「a = a」と「b = b」が問題/予期しない動作につながるのではないかと疑問に思っていましたか?コードはこの例でうまく動作します。Pythonのデフォルトの引数と引数名
def add_func(a=2,b=3):
return a+b
a=4
b=5
answer = add_func(a=a, b=b)
私が間違って証明するのが大好きですが、私は、の知っていることを感謝し
「a = a」と「b = b」が問題/予期しない動作につながるのではないかと疑問に思っていましたか?コードはこの例でうまく動作します。Pythonのデフォルトの引数と引数名
def add_func(a=2,b=3):
return a+b
a=4
b=5
answer = add_func(a=a, b=b)
私が間違って証明するのが大好きですが、私は、の知っていることを感謝し
ありません。
公式言語リファレンスはthe lexical structure of a function callと定義されています。重要なことは、「keyword_item」をidentifier "=" expression
と定義していることです。また、ここでは、呼び出しの引数がどのように解釈されるかについて述べているものです:
キーワード引数が存在する場合は、次のように、彼らは最初、 位置引数に変換されます。まず、空きスロットのリストは、仮パラメータ用に作成された です。 N個の位置が の場合、最初のNスロットに配置されます。次に、 キーワード引数ごとに、識別子が 対応スロットを特定するために使用されます(識別子が最初の形式 と同じ場合、最初のスロットが使用されます)。スロットが に既に埋め込まれている場合は、TypeError例外が発生します。それ以外の場合は、引数の値 がスロットに挿入されます( の式がNoneの場合でも、スロットはいっぱいになります)。すべての引数が に処理されると、未充填のスロットは、関数定義の対応するデフォルト値の で埋められます。
これにはいくつかのシナリオがあります。
a
とb
)があり、そしてあなたがadd_func(a=a, b=b)
のようなキーワードパラメータを使用して、関数呼び出しを指定した場合、ここでは何が起こるかだ単純なケースで 、あなたが言及したように、パラメータを保持するために作成されます。
a=
部分の「a」)が、関数のすべての仮パラメータ名と比較されます(パラメータの与えられた名前関数が定義されたとき、この場合、a
とb
)。4
!)が使用されます。したがって、Pythonはキーワード引数の "識別子"を完全に異なる方法で扱います。しかし、これはキーワード引数にのみ当てはまります。明らかに、add_func(b, a)
のようなものを試した場合、パラメータ自体はb
とa
と呼ばれますが、ではなく、は関数の仮パラメータにマップされます。あなたのパラメータは後方になります。ただし、add_func(b=b, a=a)
は問題ありません。キーワードの引数である限り、位置は重要ではありません。
グローバルオブジェクトが変更可能か不変かどうかによって異なります。あなたの整数のような不変のオブジェクトは、変更されたときにコピーされるので、安全です。リストのような変更可能なオブジェクトは、インプレースで変更され、この方法で使用するのは安全ではありません。それらに何らかの変更があっても、呼び出し間で継続され、予期しない動作を引き起こす可能性があります。
この:Pythonプログラムの既知の悪い習慣がある
def f(a=[]):
pass
:
a=[]
def f(a=a):
pass
は同じです。
ここで重要なのは、**関数呼び出し**で 'a = a'を使用することには実際には関係しませんが、これは[関数が定義されているときにデフォルトパラメータが評価される_once_](http ://docs.python.org/reference/compound_stmts.html#function)。 – voithos
これを指摘してくれてありがとう - 私はこれがかなりの人を焼いたと確信しています。 –
@ user986065:そうですね、このような場合は、デフォルトでプレースホルダの値(通常は 'None')を使用し、関数の本体でチェックすることをお勧めします(例:' aがNoneの場合:a = [] ')。 – voithos
詳細な回答ありがとうございます。私は 'a = a'を使用する習慣に慣れてきました。さまざまなものに同じ記述的な名前をつけておくことができます。すべてのコードを元に戻して変更する必要はありません。 –