Pythonの引数における参照渡しと値渡し
Pythonの引数における参照渡しと値渡しの違いは、引数に渡された変数の値が、呼び出し元と呼び出し先のどちらに影響するかという点です。
Pythonの「オブジェクトへの参照渡し」とは?
参照渡し
参照渡しでは、呼び出し元と呼び出し先が同じ変数のメモリ番地を共有します。そのため、呼び出し先で変数の値を変更すると、呼び出し元の値も変更されます。
def change_value(x):
x += 1
return x
a = 10
b = change_value(a)
print(a)
print(b)
このコードを実行すると、以下の出力が得られます。
11
11
呼び出し先で a の値を 1 増やしたため、呼び出し元の a の値も 1 増加しています。
値渡し
値渡しでは、呼び出し元と呼び出し先が異なる変数のメモリ番地を参照します。そのため、呼び出し先で変数の値を変更しても、呼び出し元の値は変更されません。
def change_value(x):
x = x + 1
return x
a = 10
b = change_value(a)
print(a)
print(b)
このコードを実行すると、以下の出力が得られます。
10
11
呼び出し先で a の値を 1 増やしたため、呼び出し先の b の値は 11 になりますが、呼び出し元の a の値は変更されません。
使い分け
参照渡しと値渡しは、どちらも一長一短があります。
参照渡し
- 呼び出し先で引数の変数の値を変更したい場合に便利です。
- 呼び出し元と呼び出し先で同じ変数を共有したい場合に便利です。
値渡し
- 呼び出し先で引数の変数の値を変更したくない場合に便利です。
- 呼び出し元と呼び出し先で異なる変数を参照したい場合に便利です。
具体的な使い分けとしては、以下のようなケースが挙げられます。
- 関数で引数の変数の値を変更したい場合は、参照渡しを使います。
- 関数で引数の変数の値を変更したくない場合は、値渡しを使います。
- 関数で引数の変数の値を変更するかどうかわからない場合は、値渡しを使います。
また、参照渡しと値渡しは、関数で引数にオブジェクトを渡す場合に特に重要です。参照渡しを使うと、呼び出し先でオブジェクトの属性やメソッドを変更することができます。値渡しを使うと、呼び出し先でオブジェクトの属性やメソッドを変更することはできません。
Python 関数の引数は値渡し?参照渡し?
Python の関数の引数は、基本的には参照渡しです。つまり、呼び出し元と呼び出し先が同じ変数のメモリ番地を共有します。そのため、呼び出し先で引数の変数の値を変更すると、呼び出し元の値も変更されます。
ただし、以下のような場合は値渡しになります。
- 引数に immutable なオブジェクト(整数、浮動小数点数、文字列、ブール値など)を渡す場合
- 引数に mutable なオブジェクトを渡す場合でも、copy() メソッドを使って値をコピーする場合
immutable なオブジェクトは、値を変更することができません。そのため、immutable なオブジェクトを関数に渡しても、呼び出し先で値を変更することはできません。
mutable なオブジェクトは、値を変更することができます。mutable なオブジェクトを関数に渡す場合は、copy() メソッドを使って値をコピーすることで、値渡しをすることができます。
以下に、値渡しになる例を示します。
# immutable なオブジェクトを渡す場合 def change_value(x): x = x + 1 return x a = 10 b = change_value(a) print(a) print(b)
このコードを実行すると、以下の出力が得られます。
10 10
呼び出し先で a の値を 1 増やしたため、呼び出し先の b の値は 11 になりますが、呼び出し元の a の値は変更されません。
# mutable なオブジェクトを渡す場合 def change_value(x): x[0] = "a" return x a = ["b", "c"] b = change_value(a) print(a) print(b)
このコードを実行すると、以下の出力が得られます。
["a", "c"] ["a", "c"]
呼び出し先で a の値を変更したため、呼び出し先の b の値も変更されます。ただし、呼び出し元の a の値は変更されません。
# mutable なオブジェクトを渡す場合 (copy() メソッドを使う場合) def change_value(x): x = x.copy() x[0] = "a" return x a = ["b", "c"] b = change_value(a) print(a) print(b)
このコードを実行すると、以下の出力が得られます。
["b", "c"] ["a", "c"]
呼び出し先で a の値を変更したため、呼び出し先の b の値も変更されます。ただし、呼び出し元の a の値は変更されません。
このように、Python の関数の引数は、基本的には参照渡しですが、場合によっては値渡しになることもあります。呼び出し先で引数の変数の値を変更したい場合は、参照渡しを使うようにしましょう。