Python関数の引数渡しの仕組みを解説!値渡しに見える理由とは
Pythonでは、関数に引数を渡すとき、その動作が「値渡し(pass by value)」なのか「参照渡し(pass by reference)」なのか迷うことがあります。結論から言うと、Pythonの引数渡しは「オブジェクトへの参照渡し(pass by object reference)」です。ただし、オブジェクトの種類によって挙動が異なるため、「値渡しのように見える」ケースがあります。
サンプルコードの出力結果
b = 30 a = ['10']
この出力を見ると、変数aの値は関数呼び出し後も変わっていないように見えます。そのため「Pythonの引数は値渡しだ」と結論づけたくなりますが、実態は少し異なります。
なぜ「値渡し」に見えるのか
ポイントは、イミュータブル(変更不可)なオブジェクトとミュータブル(変更可能)なオブジェクトの違いです。
- イミュータブルな型:整数(int)、文字列(str)、タプル(tuple)など。関数内で再代入しても、元の変数には影響しません。
- ミュータブルな型:リスト(list)、辞書(dict)、セット(set)など。関数内で要素を変更すると、元のオブジェクトも変わります。
実際のコード例で確認する
まず、イミュータブルな整数の場合:
def change_value(x):
x = 100 # ローカル変数xが新しいオブジェクトを指すだけ
num = 30
change_value(num)
print(num) # 30 のまま(値渡しのように見える)
次に、ミュータブルなリストの場合:
def change_list(lst):
lst.append('20') # 元のオブジェクト自体を変更
my_list = ['10']
change_list(my_list)
print(my_list) # ['10', '20'] に変わる(参照渡しのように見える)
まとめ
Pythonの引数には常にオブジェクトへの参照が渡されます。しかし、整数や文字列などのイミュータブルなオブジェクトは関数内で変更できないため、結果として「値渡し」のような振る舞いになります。一方、リストなどのミュータブルなオブジェクトは、関数内での変更が呼び出し元にも反映されます。
この仕組みを理解しておくと、「なぜ関数の中で書き換えたのに外の値が変わらないのか」「逆に意図せず書き換えられてしまうのか」といった疑問を防ぎ、より安全で予測しやすいコードを書けるようになります。
-
Pythonのラムダ関数(lambda)とは?基本構文と使い方を実例付きで解説
Pythonのラムダ関数(lambda関数)は、実行時にその場で生成される「名前を持たない匿名関数」です。通常、1行で記述され、特定の名前に束縛されることなく定義できます。 ラムダ関数には以下のような特徴があります。 関数の定義をその場で返すことができる return文を含まず、常に式(expression)を評価して結果を返す 関数オブジェクトが期待される場所なら、どこにでもラムダ式を記述できる ラムダ関数を使う場面 ある関数が一度しか使わず、呼び出し箇所も一箇所だけであるような場合、ラムダ関数が便利です。このようなケースでは、わざわざdef文で関数に名前を付けて定義する必要はありません
-
Pythonで関数を引数として渡す方法をわかりやすく解説
Pythonでは、関数もオブジェクトの一つとして扱われるため、他の関数の引数として渡すことができます。この仕組みを活用すると、柔軟で再利用性の高いコードを書くことができます。map()関数を使った例Pythonが標準で提供している代表的な例が、第一引数に関数を受け取る map() 関数です。map(function, iterable, ...) — iterable(イテラブル)の各要素に対してfunctionを適用し、その結果を返します。もちろん、独自に定義したカスタム関数でも、引数として関数を受け取るように実装できます。自作関数sqr(x)を引数として渡すここでは、リストの各要素を2乗す