Python♪関数に引数で渡された変数の変更が、関数の外側に与える影響。

 関数の引数(ひきすう)は、関数名の後ろの()の中に記載した変数や値のことで、引数により、関数内部にデータを渡すことができます。しかし、関数の内部でこの値を変更したときに、関数の外部にはどの様な影響があるのでしょうか。実は、それは、引数によるデータの受け渡しが「参照渡し」であることから簡単に理解できるのです。

 では、早速、どのような影響が生じるのか試してみましょう。コード01では、関数test1()に引き渡された実引数x1, x2, x3はそれぞれ、[2], [2], 2です。それに対して、関数内での変数の値の変更により、関数の外で[5], [2], 2となります。つまり、関数の外に影響を与える場合と、影響を与えない場合があることがわかります。おそろしや、おそろしや~。

#コード01
def test1(x1, x2, x3):
    x1[0] = 5 #要素の変更 → 関数の外の値も連動する。
    x2 = [5] #再定義(初期化)→ 関数の外のx2と関数内のx2は全くの別物
    x3 = 5 #再定義(初期化)→ 関数の外のx2と関数内のx2は全くの別物
    print('関数内部計算後のx1, x2, x3 =', x1, x2, x3)
x1 = [2]
x2 = [2]
x3 = 2
print('関数受け渡し前のx1, x2, x3 =', x1, x2, x3)
test1(x1, x2, x3)
print('関数実行後のx1, x2, x3 =',x1, x2, x3)
#出力01
関数受け渡し前のx1, x2, x3 = [2] [2] 2
関数内部計算後のx1, x2, x3 = [5] [5] 5
関数実行後のx1, x2, x3 = [5] [2] 2

 

しか~し、以下の記事を読んでいれば、恐るるに足りません。だから、必ず読んでね。

「参照渡し後の要素の変更」と「参照渡し後の再定義」の違い

 引数は、関数の外側の実引数から関数の内側の仮引数への参照渡しですから、関数の中でどのような変更を行ったかを見れば、結果はすぐにわかります。

 まず、x1[0] = 5。これは、左辺を見るとx1[0] =となっており、要素の変更を行っています。つまり、関数の外にも影響を与えるのです。

 一方、x1 = [5], x3 = 5の方の左辺を見てみましょう。こちらは、それぞれ、x1 =, x3 =となっており、変数が再定義されています。「変数の再定義」は、今の場所を消して上書きするのではなく、現在の記憶場所を放置し、別の記憶場所に定義し直します。つまり、仮引数と実引数は再定義を行った時点で、それぞれ独立した全く別の変数になっています。したがって、関数の外には影響しません。

 どうでしょうか?参照渡しの内容を正しく理解しておけば、「関数の引数って参照渡しなんだ~。なるほど、それでこんな結果になるんだね~。」でおしまいです。でも、簡単とはいっても知らないと怖いですので、きちんと覚えておきましょう。