コンテンツ

Pythonインタラクティブガイド - ステップ3 関数 (4) - 引数の代入 (代入渡し)

シリーズ - Pythonインタラクティブガイド
Info
  • 本講座「Pythonインタラクティブガイド」は、手を動かしながらPythonプログラミングの基礎を学べるインタラクティブな講座です。
  • 「スタイルガイド」では、Pythonで読みやすくきれいなコードを書くためのガイドライン(PEP8)を主に紹介しています。
  • 各コード例はその場で実行して結果を確認できます。
    ページ再読み込みで元に戻るので、自由に試してみてください。

「ステップ3 関数」の続きです。

Pythonでは、関数に引数を渡すとき、その引数はパラメータ変数に代入されて処理が行われます。
この仕組みは「代入渡し (pass by assignment)」や「オブジェクト参照渡し (pass by object reference)」と呼ばれます。

他のプログラミング言語では「値渡し」や「参照渡し」という概念がありますが、Pythonはこれらとは少し異なる独自のメカニズムを持っています。

ここで、1.4. 変数と代入で説明した「代入」について簡単におさらいしましょう:

「代入」とは
  • Pythonでは、「代入」は「値にラベル(変数)を付ける操作」です。
    • 変数の値を別の変数に代入すると、値が移動するのではなく、両方の変数が同じ値を参照します。
  • 変数への「再代入」は「ラベルを別の値に付け替える操作」です。
    • 「再代入」は、変数に紐付く値自体に変更を加えるのではなく、新しい値に変数の参照先を変更します。

このことを踏まえて、以下のコードを見てみましょう:

このように、関数内でパラメータの変数に再代入を行っても、もとの引数の値は変化しません。
(「再代入」が行われて、ローカル変数lstの参照先が変わるだけです)

次のコードはどうでしょうか:

この場合、グローバル変数 prices は関数呼び出し後に値が変化しています。
これは、関数 append_item を呼び出した際に:

  1. ローカル変数 lst にグローバル変数 prices の値が代入される (lstpricesが同じ値を参照する)
  2. lstが参照するオブジェクトの要素をappendメソッドで更新する

という動作となっているため、関数呼び出し後にpricesの値が更新されています。

📚練習問題

次のプログラムの動作を予想してから実行してみましょう:

解答例
📚練習問題2

次のプログラムの動作を予想してから実行してみましょう:

解答例
引数の代入 (代入渡し) まとめ
  1. Pythonでは、引数はパラメータに代入して関数に渡される (代入渡し)
  2. 関数内でパラメータ変数に再代入を行っても元の値は変化しない
  3. (appendメソッドのような)パラメータの要素を変更する操作は元の値も変化する

以上を踏まえて、引数を渡す際に気をつけるべきポイントを整理しましょう:

関数に引数を渡すときの注意点
  • イミュータブルな引数(例:整数、文字列など)は、関数に渡しても元の値は変化しない
    • 値を変えたい場合は、変更後の値を戻り値として受け取り、元の変数に再代入する
  • ミュータブルな引数(例:リスト、辞書など)は、要素を変更する操作によって元の値も変更される
    • 変更を避けたい場合は、関数の冒頭でコピー(必要に応じて、深いコピー)を作成してから処理を行うとよい
📚練習問題

リストと文字列を入力すると、リストの末尾に文字列を追加したリストを返す関数 add_task を作成しましょう。
ただし、元のリストを変更しないようにしてください。

(例: add_task(["買い物に行く", "メールを送る"], "本を読む")=>["買い物に行く", "メールを送る", "本を読む"])

解答例

関連記事