見出し画像

【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言語のヘビーユーザならこういうんだろうな。

「変数のコピーが増えて処理時間が増えそうだ」

はてさて。

この記事が気に入ったらサポートをしてみませんか?