Pythonの引数の引き渡し

提供: tknotebook
2018年9月11日 (火) 05:33時点におけるNakamuri (トーク | 投稿記録)による版

移動: 案内検索

メインページ>コンピュータの部屋#Python>Python Tips


pythonは大変わかりやすい言語ですが、ひとつわかりにくい基本的な事項があります。 関数への引数の引き渡し方です。

引数の引き渡し方といえば

  1. 値渡し(Call By Value)
  2. 参照渡し(Call By Reference)

の2種類が定番ですが、pythonでは見かけ上全く同じ書き方でこの2種類が入り混じります。

例えば

def fun(a):
  a = "foo"

b="bar"
fun(b)
print(b)

を実行すると

bar

と表示されて 値渡しは明らかです。

しかし

def fun(a):
  a.append(3)

b = [1, 2]

fun(b)

print(b)

は [1, 2, 3] を出力します。

このあたりの違いはどうなっているのでしょうか?

ここではこの点について解説します。

全てのデータがオブジェクト

pythonでは全てのデータはオブジェクト型です。変数はオブジェクトの「参照」を保持します。

int や float や str もオブジェクトなのです。

引数は値渡し(Call By Value)

pythonで全ての引数は「値」で渡されます。Call By Value です。但し渡されるのはオブジェクトの参照です。

ならば実質的に 参照渡し(Call By Reference)になるのではと短絡的に考える人もいるかもしれませんが、 よく考えてみましょう。一般に 参照渡し(Call By Reference)と呼ばれているもの「参照」変数の参照です。 オブジェクトの参照ではありません。python が値渡しで渡す参照はオブジェクトの参照です。

整数や文字列と immutable

一度作成されると変更できないオブジェクトを immutable と言います。python では基本的な数値型(int, float), str型、bool型はimuutableです。

imuutableなオブジェクトを関数の引数に渡すと 実質的に値渡しになります。

def fun(a):
  a = "foo"

b="bar"
fun(b)
print(b)

で、bに代入される "bar" は新たに新規作成されたオブジェクトで、aにだいにゅうされている "foo" 文字列オブジェクトとは無関係だからです。


int float str tuple bool range type(None)


その他にもこんなのがあります。

bytes complex frozenset slice type type(Ellipsis) type(NotImplemented) types.FunctionType *これは mutable, 後述します。 types.BuiltinFunctionType weakref.ref