9. Pythonにポインターはないの?

C/C++の学習の難関のひとつがポインターの扱いだと言われています。 C/C++のポインターは習熟すれば非常に強力な武器とな理ます。その一方で 使い方を誤れば、システムを破壊することにもなりかねない力を持つ 、”最後の武器"とも言えるでしょう。

そう思って改めてPythonを見ると、pythonのデータ型の中には ポインター型は有りませんし、ポインターを操作するためのオペレーターや関数も存在しません。 同じプログラム言語なのに?と思われませんか?

実は、Pythonでは(そしてJavaでも)、変数の意味がC/C++とは異なっています。 あえて乱暴な言い方をすれば、"Python(Java)では全ての変数はポインター”なのです。

C/C++では、変数は次の様に宣言されます。

long l;
double f;
long *pl=&l;
double *pf = &f;

この例では、 l, f が変数名で、 pl, pf がそれらの変数へのポインタを保持するポインタ変数ということになります。 変数の値を変更すると、変数名に割り当てられたメモリ領域にストアされた値が変更されていることが分かります。

l=1;
printf("l=%ld, pl=0x%p, *pl=%ld \n", l, pl, *pl);
l+=1;
printf("l=%ld, pl=0x%p, *pl=%ld \n", l, pl, *pl);
% clang pointer.c
% ./a.out
l=1, pl=0x0x304edb708, *pl=1
l=2, pl=0x0x304edb708, *pl=2

一方pythonで同様のプログラムを実行して見ると、

1a=1
2b=2
3print("a= {} id(1)={} id(a)={}".format(a , id(1),  id(a)))
4print("b= {} id(2)={} id(b)={}".format(b , id(2),  id(b)))
5a += 1
6print("a= {} id(1)={} id(a)={}".format(a , id(1),  id(a)))
7print("a= {} id(2)={} id(a)={}".format(a , id(2),  id(a)))
8print("b= {} id(2)={} id(b)={}".format(b , id(2),  id(b)))
a= 1 id(1)=4563593520 id(a)=4563593520
b= 2 id(2)=4563593552 id(b)=4563593552
a= 2 id(1)=4563593520 id(a)=4563593552
a= 2 id(2)=4563593552 id(a)=4563593552
b= 2 id(2)=4563593552 id(b)=4563593552

というように、変数 aの値を変更すると、そのid (メモリアドレスに相当)が変わってしまうことが分かります。 またその値は、変数aの値となっているオブジェクトのidと同じとなっています。このように、pythonでは変数は、 メモリ領域につけられた名前ではなく、その値のオブジェクトを示すポインタの様な物と思った方が間違いがありません。

1var('x y')
2y=(1+x)**20
3show(y.expand())