Python関数の引数は「参照の値渡し」である
Pythonの公式チュートリアルによると、Pythonでは関数の引数はすべて「参照の値渡し」のようです。
The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object).
検証
Python 3.9.5で検証。
- 参考: 組み込み関数 id() の仕様
def f1( a ):
print("#1: {} {}".format(a, hex(id(a))))
if type(a) is list:
a.append(40);
elif type(a) is tuple:
a += (40, )
else:
a += 40
print("#2: {} {}".format(a, hex(id(a))))
mylist = [10,20,30];
print("\n#0: {} {}".format(mylist, hex(id(mylist))))
f1(mylist)
mytuple = (10,20,30)
print("\n#0: {} {}".format(mytuple, hex(id(mytuple))))
f1(mytuple)
myint = 1
print("\n#0: {} {}".format(myint, hex(id(myint))))
f1(myint)
myint2 = myint
print("\n#5: {} {}".format(myint2, hex(id(myint2))))
実行結果
#0: [10, 20, 30] 0x1f813e86d80
#1: [10, 20, 30] 0x1f813e86d80
#2: [10, 20, 30, 40] 0x1f813e86d80
#0: (10, 20, 30) 0x1f813e92300
#1: (10, 20, 30) 0x1f813e92300
#2: (10, 20, 30, 40) 0x1f813e8c360
#0: 1 0x1f813c86930
#1: 1 0x1f813c86930
#2: 41 0x1f813c86e30
#5: 1 0x1f813c86930
考察
- 関数の引数がimmutableであろうとmutableであろうと、すべて「参照値の値渡し」となる
- 関数内でimmutableに対する演算を行った際に、新しいオブジェクトが生成され演算結果が格納される(関数を呼び出す前にコピーが生成されるわけではない)
- 別の変数に代入しただけでは、オブジェクトのコピーが生成されるわけではない