Pythonで関数を呼び出す時に参照渡しで呼び出し元の変数を直接関数の中で書き換えたかった
Pythonで関数を呼び出す時の引数を参照渡し
にして、呼び出し元の変数を直接関数の中で書き換えたかった時に躓きました。イミュータブル
が良いとされている世の中ですが、どうしても参照している値のインデックスを呼び出し元の変数と直接関数の中とで共有したかったという状況です。この悩みの原因はそもそもPythonで関数を呼び出す時に参照渡し
になっているところにあるのですが、同じように悩む人がいるかもしれないので詳細な仕組みについてまとめます。
参照渡しと値渡し
値渡し
が引数の値をコピーして渡す方法で、独立してメモリ上に値を保管します。参照渡し
がメモリアドレスを渡す方法で、呼び出し元と関数の中で同じ値を参照します。
Pythonのミュータブルとイミュータブル
ミュータブル
な値はリスト、セット、ディクショナリなどです。部分的な値を変更が可能(メモリ上の値自体
の変更が可能)です。
イミュータブル
な値はタプル、数値型、文字列、ブーリアン、Noneなどです。注意するべきは、イミュータブル
な値でも再代入
は可能なことです。仕組みとしては、変数にメモリの番地
が入っており、再代入するとメモリの番地
が変更される、ということになります。一応コードで具体例を示します。
a = 5 b = a #この時点ではメモリの番地は同じ b = 1 #ここでbのメモリの番地が変わる
Pythonは変数にメモリの番地
を持っているため、値渡し
と参照渡し
という切り口ではなく、ミュータブル
とイミュータブル
と言う切り口で捉えるのが適切です。Pythonではメモリの番地
を直接操作するような低レイヤの事柄は基本的に見えません。
ここまででわかるように、私が悩んだ
呼び出し元の変数を直接関数の中で書き換えたかった
はPythonではできないようです。