🔖

Pythonで値渡しと参照渡しについて考える。

2023/03/28に公開
1

プログラミングの基礎である値渡と参照渡しについてコードのサンプルを作成しながらまとめていきます。

値渡し

値渡しは、関数に引数の値をコピーして渡す方法です。関数内で引数の値が変更されても、元の変数の値は影響を受けません。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

junerjuner

その参照渡しは参照渡しではなくて値渡しでは(参照渡しではないのでは?(渡した引数自体は上書きされていないため