Python♪基本:変数の数値の変更とパソコン内での参照先アドレス。

中1のゆうちゃんに、どこまで説明するか迷ったけれど、変数への値の代入とパソコン内での参照先アドレスについて説明することにしました。コンピューターのメモリー上でのデータの扱いを、ほとんど意識しなくてもよい言語もあります。でも、私はPyrhonは覚えた方がよい言語だと思います。

ゆうちゃんに「集合型を探してみて。でも、目次はみないで。」とPythonチュートリアルの本を渡しました。すると、(なにをやらせるんだ~)というような怪訝な顔をしながら、すぐに後ろの索引を見て、集合型を見つけてしまいました。(予定と違う~。)
「ちっ、つまんない。そのとおり。」(気を取り直して)
「でも、索引がなかったら、探すの大変だよね。これと同じで、パソコンのメモリーにデータを保存するときには、本の索引のようなアドレス帳が作られてるのよ。」(ゆうちゃんが、ああ、そういう展開ねっていう顔をする)
「そして、郵便物を届けるのに住所が必要なように、パソコンのデータを記憶している領域は、それぞれの場所にアドレス番号が決まっているの。だから、例えば変数xの中身を調べるときは、パソコンは、アドレス帳で何番のアドレスにデータが記憶されているのかを調べて、変数の中身を取り出すしくみになってるんだよ。難しい?」
「べつに~」
「それじゃぁ、まず、C言語とPythonを比べてみよう。」(ゆうちゃん、目がきらりん)

実は、ゆうちゃんの一番上のお兄ちゃんは、大学生でC言語を勉強しているらしい。だから、「C言語」というキーワードにゆうちゃんは弱いのです。
このために、Visual StudioインストールしてC++使える環境構築しました。

という具合で、難解(?)参照先アドレスの説明のはじまり、はじまり~。

0.ゆうちゃんとPythonシリーズ

この記事は「ゆうちゃんとPythonシリーズ」の記事です。一連の記事は、以下のリンク集を参照してください。

中学生のゆうちゃんとPythonシリーズ

なお、それぞれの記事は、シリーズの中でそれまでに習った文法を使ってサンプルコードを考えています。実際には、もっと、効率のよい書き方があるかもしれませんが、ご了承ください。

1.参照先アドレスを勉強する前に

参照先アドレスの勉強をする前に、以下の記事の前半の「1.変数への数値の代入」の部分を読んでおきましょう。

コンピューターの変数記憶には、参照先のアドレス(id)が使われる。

2.C言語の変数の型宣言と値の変更

コード01はC言語です。内容を細かく読み込む必要はありません。どの行がどんな内容の命令文なのか、概要だけ理解してください。

4行目の「int x;」は変数xの型宣言です。ここでは整数型であることが宣言されています。
5行目の「x = 10;」は変数xに整数10を代入しています。
6行目はxの内容を出力しています。
7行目は変数xに入っている整数10が、コンピューターのメモリーの何番のアドレスに保存されているのかを出力します。出力01を見ると、整数10の保存先のアドレス番号(参照先アドレス)は、「00B3FA90番」であることがわかります。
9行目の「x = 20;」では、変数xの内容を10から20に変更します。
10行目は再びxの内容を出力し、
11行目では変数xがパソコン内で参照している参照先アドレスを出力します。

出力01を見ると、変数の内容を10から20に変更しても、参照先アドレスは00B3FA90のまま、変わっていません。

//コード01
int main()
{
	int x
	x = 10;
	printf("値は%d\n", x);
	printf("アドレスは%p\n", &x);

	x = 20;
	printf("値は%d\n", x);
	printf("アドレスは%p\n", &x);

    return 0;
}
//出力01
値は10
アドレスは00B3FA90
値は20
アドレスは00B3FA90

これを、図で表します。右下の図は「int x;」という命令文を実行したときのイメージ図です。変数xという箱を00B3FA90番地に用意しましたが、箱の中身はまだ空です。
左側の図はパソコン内で、どのようにメモリー内でデータが保存されているのかを示す図です。左上はアドレス帳(本の索引のようなもの)で、変数xの中身は00B3FA90番地に保存されていることが記録されています。そして、左下の図に示すように、00B3FA90番地に整数10が保存できるだけの領域を確保します。

次に、「x = 10;」により、変数xに整数10を代入しました。右下のイメージ図では、用意された箱の中に10が入りました。左の図では、00B3FA90番地に整数10が記録されました。

次に、「x = 20;」により、変数xに20を代入しました。右下のイメージ図では、もともと保存されていた10を20に入れ替えています。左の図では、00B3FA90番地のデータが整数20に上書きされました。

以上が、C言語における、変数への数値の代入、変更とパソコン内でのデータの記憶の仕組みです。変数の説明は、箱の中にデータを入れる説明が多く、C言語はまさに、その説明にぴったりです。Pythonの勉強なのにC言語の説明を先にしたのは、そのような理由からです。

3.Pythonの変数の定義と値の変更

Pythonは、変数の値を変更したときのパソコン内での記憶の仕方が、C言語とは少し違います。この内容に、初心者の段階で踏み込むかどうかは、意見がわかれるところかもしれません。しかし、わたしは初心者こそ知っておくべきことだと思います。関数の引数、浅いコピー、スコープ等を勉強するときに役に立ちます。
私もPythonの勉強では、パソコンのメモリーの参照なんてパソコン内部の仕組みに踏み込むつもりはありませんでした。全然、ブラックボックスでO.K.というスタンスだったのです。でも、勉強を進めるうちに混乱しはじめ、仕方なくメモリーの参照を確認し、ようやく、わかったという経緯があります。
ここまで読んでビビっている人もいるかもしれませんが、そんなに難しいことではありません。

以下のコード02では、id()という関数を使っています。id(x)とすると、変数xが参照しているアドレス(参照先アドレス)がわかります。それではコードの説明を始めます。
2行目の「x = 10」ではxに10を代入しています。
3行目の「print(‘値は’, x)」は、’値は’という文字列と、xという変数を同時に出力します。
4行目ではid()関数を使って、変数xの入っている10が保存されたアドレスを出力します。
6行目の「x = 20」ではxの内容を20から10に変更します。
7行目では変数xに代入された値を出力します。
8行目では変数xの参照先アドレスを出力します。

このコードでのポイントは、変数xの内容を20に変更することで、参照先アドレスも1726508384から、1726508704に変化しているところです。

#コード02
x = 10
print('値は', x)
print('アドレスは', id(x))

x = 20
print('値は', x)
print('アドレスは', id(x))
#出力02
値は 10
アドレスは 1726508384
値は 20
アドレスは 1726508704

それでは、図で説明します。「x = 10」という命令文を実行すると、型宣言と、変数xへの10の代入を同時に行います。型宣言とは、整数を保存するのに必要な領域をパソコンの中に確保することです。この例では、176508384番地のメモリーを変数xのために確保しました。
右下のイメージ図は、変数aの箱を176508384番地に確保し、その箱の中に整数10を入れたことを表現しています。
左の図は、パソコン内で、どのようにメモリー内でデータが保存されているのかを示す図です。左上のアドレス帳に変数aが参照するアドレス176508384番地を記録し、左下のデータ保存領域の176508384番地に記憶領域を確保し、更に176508384番地に整数10を保存しました。

次に、「x = 20」により、変数aの内容を10から20に変更しました。しかし、このとき、C言語の場合とは異なり、変数aの参照先アドレスは176508384番地から、176508704番地に変化しています。これは、右下のイメージ図のようになります。10が記憶されていた176508384番地のデータはそのまま放置し、全く別の176508704番地にデータの記憶領域を新しく作り、その中に20を代入しています。
これは、例えば友達と遊ぶ日が8/6から8/13に変更になったときの手帳の使い方に似ています。真面目なC言語君は、8/6を消しゴムで消して、同じ場所に8/13と書き直します。一方、Pythonちゃんは、もとの8/6の記録は消しゴムで消さずにそのまま放置し、別の場所に8/13と追記します。
図の左側を見てみましょう。x = 20とすることで、データの保存先のアドレス帳の内容を、176508384番地から、176508704番地に書き換えました。そして、新しい176508704番地に整数20を代入しているのです。
つまり、C言語では内容を「変更」しているのですが、Pythonでは変更のように見えますが、実際には同じ名前の変数を新しく作り直し、「再定義」しているのです。

まだ、もう少し勉強を進めないと、この違いを理解する重要性はわからないと思いますが、大切なことですので理解しておきましょう。

「ちょっと、難しいかな~」と思ったんですが、ゆうちゃんに言わせると「楽勝」だそうです。怪しい気もしますが、ゆうちゃんに「じゃあ、説明してみて」と言うと、ちゃんと説明できていたので、ほっと、一安心。

4.まとめ

(1) id()関数で、変数の参照先アドレスを調べることができます。

(2) 変数の内容を変更したときに、C言語は、新しい値をパソコンのメモリーの同じ場所に上書き保存します。

(3) 変数の内容を変更したときに、Pythonは、変更前のデータは放置し、全く別の場所に新しいデータを保存します。これは、内容の「変更」というよりも、同じ名前の変数を新しく作り直し「再定義」していると言える。

(4) C言語とPythonの変数の内容の変更の違いを例えると、メモ帳で消しゴムをつかうかどうかの違いです。例えば友達と遊ぶ日が8/6から8/13に変更になったとき、真面目なC言語君は、8/6を消しゴムで消して、同じ場所に8/13と書き直します。一方、Pythonちゃんは、もとの8/6の記録は消しゴムで消さずにそのまま放置し、別の場所に8/13と追記します。

私が実際に購入した教材のご紹介

以下、私が実際に購入したPythonの教材をまとめてみました。 Pythonを学習する上で、少しでもお役に立つことができればうれしいです。

Python♪私が購入したPythonの書籍のレビュー

UdemyのPythonの動画講座を書籍を買う感覚で購入してみた