1. はじめに
Pythonを学ぶ上で、「値渡し」と「参照渡し」の違いは必ず理解しておきたい基本事項です。関数に引数を渡したとき、元の変数に影響があるのか、ないのか——これはバグの原因にもなりがちなポイントです。
本記事では、Pythonにおける「値渡し」と「参照渡し」の概念をわかりやすく解説し、実際のコード例とともに理解を深めていきます。初心者から中級者まで、「どうやって渡されるのか?」「どう影響するのか?」を丁寧に解説していきます。
2. Pythonにおける「値渡し」と「参照渡し」の基本
2-1. Pythonは値渡し? 参照渡し?
Pythonでは、厳密には「値渡し(pass by value)」でも「参照渡し(pass by reference)」でもなく、「オブジェクトの参照を値として渡す」という形式をとっています。これを「参照の値渡し(pass-by-object-reference)」とも呼びます。
2-2. イミュータブル型とミュータブル型
Pythonのオブジェクトには「変更できない型(イミュータブル)」と「変更できる型(ミュータブル)」があります。この違いが、関数に引数を渡すときの挙動に大きく影響します。
- イミュータブル型: int, float, str, tuple など
- ミュータブル型: list, dict, set など
2-3. 基本的なコード例
例:イミュータブル型(int)
def update_number(x):
x = x + 10
print("関数内のx:", x)
num = 5
update_number(num)
print("関数外のnum:", num)
実行結果:
関数内のx: 15
関数外のnum: 5
解説:int型はイミュータブルなので、関数内で変更しても元の変数には影響がありません。
例:ミュータブル型(list)
def update_list(lst):
lst.append(100)
print("関数内のlst:", lst)
my_list = [1, 2, 3]
update_list(my_list)
print("関数外のmy_list:", my_list)
実行結果:
関数内のlst: [1, 2, 3, 100]
関数外のmy_list: [1, 2, 3, 100]
解説:list型はミュータブルなので、関数内で変更すると元の変数にも影響します。
3. よくある使い方・応用例
3-1. 関数内でリストを安全に操作する方法
元のリストを変更せずに新しいリストを作るには、コピーを使います。
def safe_update_list(lst):
new_lst = lst.copy()
new_lst.append(999)
print("コピー後のリスト:", new_lst)
original = [10, 20, 30]
safe_update_list(original)
print("元のリスト:", original)
実行結果:
コピー後のリスト: [10, 20, 30, 999]
元のリスト: [10, 20, 30]
ポイント:関数内で元のリストを変更したくない場合は、copy()
やlist()
を活用しましょう。
3-2. ディクショナリ(dict)の参照渡し
辞書型もミュータブルなので、関数で直接更新されます。
def update_dict(d):
d["new_key"] = "new_value"
my_dict = {"a": 1}
update_dict(my_dict)
print(my_dict)
実行結果:
{'a': 1, 'new_key': 'new_value'}
4. 注意点・エラー対策
4-1. 引数の影響を予期しないバグ
ミュータブル型を渡した場合、元のオブジェクトが書き換わる可能性があります。意図的でない変更はバグの原因になります。
4-2. ミュータブル型のデフォルト引数に注意
Pythonでは関数のデフォルト引数にミュータブル型を使うと予期しない挙動になります。
def add_item(item, lst=[]):
lst.append(item)
return lst
print(add_item(1))
print(add_item(2)) # 意図しない結果になる
実行結果:
[1]
[1, 2]
対策:デフォルト値はNone
を使い、関数内で初期化する方法が安全です。
def add_item_safe(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
5. まとめ
- Pythonの関数引数は「参照の値渡し」である
- イミュータブル型は影響されず、ミュータブル型は変更が反映される
- 予期せぬ動作を防ぐには
copy()
やNone
の活用がポイント
実務でのポイント:データ加工やAPIレスポンスの処理などで、元データを壊さずに処理する技術として非常に重要です。
学習のコツ:まずはリストや辞書を関数に渡してみて、「何が起こるか」を実験することから始めましょう!