Pythonで値渡しと参照渡しについて考える。
プログラミングの基礎である値渡と参照渡しについてコードのサンプルを作成しながらまとめていきます。
値渡し
値渡しは、関数に引数の値をコピーして渡す方法です。関数内で引数の値が変更されても、元の変数の値は影響を受けません。Pythonでは、イミュータブル(変更不可)なオブジェクトが値渡しの対象となります。例えば、数値、文字列、タプルなどです。
def update_value(x):
x = x * 2
print("x in function:", x)
x = 10
update_value(x)
print("x outside function:", x)
x in function: 20
x outside function: 10
この例では、update_value関数内で引数xの値が変更されていますが、関数の外側で定義された変数xの値は変わっていません。これは、関数に値渡しが行われ、元の変数の値が影響を受けないためです。
参照渡し
参照渡しは、関数に引数のメモリアドレス(参照)を渡す方法です。関数内で引数の値が変更されると、元の変数の値も影響を受けます。Pythonでは、ミュータブル(変更可能)なオブジェクトが参照渡しの対象となります。例えば、リスト、辞書、セットなどです。
def update_list(lst):
lst.append("Python")
print("lst in function:", lst)
lst = ["Java", "C++"]
update_list(lst)
print("lst outside function:", lst)
lst in function: ['Java', 'C++', 'Python']
lst outside function: ['Java', 'C++', 'Python']
この例では、update_list
関数内で引数lst
の値が変更されており、関数の外側で定義された変数lst
の値も変わっています。これは、関数に参照渡しが行われ、元の変数の値が影響を受けるためです。
コピーを作成する
元の変数に影響を与えたくない場合は、関数内で引数のコピーを作成し、そのコピーに対して処理を行うこともできます。これにより、関数外の変数の値が変更されることを防ぐことができます。ただし、大きなデータ構造をコピーする際には、メモリ使用量や処理速度に注意が必要です。
def update_list_without_affecting_original(lst):
lst_copy = lst.copy()
lst_copy.append("Python")
print("lst_copy in function:", lst_copy)
lst = ["Java", "C++"]
update_list_without_affecting_original(lst)
print("lst outside function:", lst)
lst_copy in function: ['Java', 'C++', 'Python']
lst outside function: ['Java', 'C++']
この例では、update_list_without_affecting_original
関数内で引数lst
のコピーを作成し、そのコピーに対して処理を行っています。そのため、関数の外側で定義された変数lst
の値は変更されません。この方法で、関数内での処理が元の変数に影響を与えずに済みます。
まとめ
Pythonにおける値渡しと参照渡しについて解説しました。
値渡しはイミュータブルなオブジェクト(数値、文字列、タプルなど)に適用され、関数内で引数の値が変更されても元の変数の値に影響がありません。
一方、参照渡しはミュータブルなオブジェクト(リスト、辞書、セットなど)に適用され、関数内で引数の値が変更されると元の変数の値に影響があります。
また、関数内で引数のコピーを作成し、そのコピーに対して処理を行う方法を紹介しました。これにより、関数外の変数の値が変更されることを防ぐことができます。
Discussion
その参照渡しは参照渡しではなくて値渡しでは(参照渡しではないのでは?(渡した引数自体は上書きされていないため