【Python】関数引数は値渡しのみ、値を返すのはリターン文のみ、という徹底さ
昨日はまっていたのは、結局この一点でした。
これがコード。
def foo(a) :
print(' foo a (1) ', hex(id(a)), a)
a = 22
print(' foo a (2) ', hex(id(a)), a)
def boo() :
a = 1
print('boo a (1) ', hex(id(a)), a)
foo(a)
print('boo a (2) ', hex(id(a)), a)
boo()
こちらが実行結果。
boo a (1) 0xeb483568 1
foo a (1) 0xeb483568 1
foo a (2) 0xeb4836b8 22
boo a (2) 0xeb483568 1
関数「boo」から、
関数「foo」を引数「a」で呼び出します。
関数「foo」で「a」を書き換えますが、
関数「boo」には伝わりません。
「foo」は「boo」の変数「a」を参照することはできないのです。
「参照渡し」ではなく
「値渡し」ということです。
・引数は値渡しのみ
・値を返すのはリターン文のみ
なんという徹底さだろう。
Cで不具合の元とも言われた参照渡し、
すなわちポインタ渡しを撲滅したのでしょう。
面白いのは、「foo」に入った時点では「id」が同じだということです。「id」が置き換わるのは、「foo」が「id」を変更した瞬間。できる限りは同じ「id」を使う。無理とわかった時点で複製する。そんな感じでしょうか。インタプリタらしい動きではあります。
引数がリストや辞書の場合も気になりますが、それはまたそのうちに調べよう。
関数から値を得る方法はただ一つ。
リターン文だけです。
でも、通常リターン文は一つのデータしか返しません。
どうすれば複数のデータを返すことができるのでしょうか。
リターン文において、「,」で区切って複数の値を書き連ねればいいようです。
def foo() :
a = 1
b = 2
c = 3
return a, b, c
x, y, z = foo()
print('x, y, z = ', x, y, z)
こちらが実行結果。
x, y, z = 1 2 3
引数をズラズラと並べることに慣れ親しんできた私には、戻り値をズラズラ並べるというのはかなり衝撃的でした。
異なる言語に触れるというのは面白い。
いつも使っている言語の問題点も見えてきます。
でも、C言語のヘビーユーザならこういうんだろうな。
「変数のコピーが増えて処理時間が増えそうだ」
はてさて。