何らかの方法で作成されたオブジェクトに、プログラムコードからアクセスするために使うのが「変数」だ。本連載では何度も触れているが、変数とは「オブジェクトに付けたラベル」のようなものだと考えるのがPythonではしっくりとくる。
Pythonのドキュメント「名前の束縛」には「名前 (name) は、オブジェクトを参照します」とある。この「名前」の一つが「変数」(変数名)だ。変数にすることで、その変数が「Pythonのオブジェクトを参照する」ようになる。このことを「束縛」(オブジェクトと名前を関連付ける)ということもある。
def文による関数定義も同様だ。これは関数を表すオブジェクトを作成して、それと「関数名」という「名前」と関連付ける操作だ。
このときに注意したいのは、型を持つのはオブジェクトであり、変数ではないことだ。つまり、以下のコードはエラーとはならない。
mylist = [1, 2, 3] # 変数mylistにリストを代入(名前の束縛が行われる)
print(mylist)
mylist = (1, 2, 3) # 変数mylistにタプルを代入(名前の再束縛が行われる)
print(mylist)
実行結果を以下に示す。
関数(の名前)でもこれは同じだ。
def hello():
print('Hello')
hello()
hello = 'abc'
hello()
これを実行すると次のようになる。
最初のhello関数呼び出しでは、きちんと関数が実行される。が、次の呼び出しはエラー(TypeError例外)となる。これは、その前の代入文で「hello」という名前が文字列に束縛されたからだ。このとき、最初に定義した関数の実体(オブジェクト)には既にアクセスする手段がないことにも注意しよう。あるオブジェクトを参照するものがなくなったら(あるオブジェクトとの束縛が全くなくなったら)、適当なタイミングでPythonがそうしたオブジェクトをメモリ上から自動的に削除する。こうした機構を「ガベージコレクション」と呼ぶ。
今見たように変数や関数名などの「名前」はオブジェクトに付けるラベルのようなものでしかないので、変数への再代入は単なるラベルの付け替えでしかない。Cなどの静的型付け言語に慣れている方にとっては、このことは少し意外かもしれない。
ただし、変数には異なる型のオブジェクトであっても代入可能だからといって、実際のプログラムでそういった処理を行うことは、混乱を招く素となる(上のコードでは変数mylistにタプルを代入したが、「mylist」という名前とその値であるタプルとは相違がある。リストなのかタプルなのかがコードを読んでも明確ではない。これは意図した行為なのか、バグなのかが分からないということだ)。そのため、このようなことはなるべくしないようにすることが推奨される。
これまでにも何度か見てきたdel文は、実は変数とオブジェクトとの間の束縛を取り消すものだ。「オブジェクトを削除する」というよりは、「名前とオブジェクトの束縛を削除する」操作だと考えておこう(最終的な結果は同じではあるが)。
mystr = 'Hello Python' # 「mystr」と文字列'Hello Python'を束縛
yourstr = mystr # 「yourstr」も同じ文字列を参照する
del mystr # 「mystr」と文字列'Hello Python'との束縛を取り消す
print(yourstr) # この時点ではまだ文字列'Hello Python'への参照はある
del yourstr
print(yourstr) # もう「yourstr」という名前はない
実行結果を以下に示す。
最後にエラー(NameError例外)が発生するまでの道のりを考えてみよう。
最初の2行が実行されることで、文字列'Hello Python'は2つの変数から参照されるようになる。次にdel文で「mystr」との束縛を削除しても、文字列'Hello Python'と「yourstr」との束縛は残ったままだ。そのため、print関数呼び出しでは、その値を利用できる。しかし、その次にdel文で「yourstr」と文字列の束縛を削除すると、そのオブジェクトにはもうアクセスできなくなり、最後のprint関数呼び出しはエラーとなる。
アクセスできなくなった文字列'Hello Python'は、先ほど述べたガベージコレクション機構によって削除される。
今回はPythonのオブジェクトの基本的な事柄について見てきた。次回は今回取り上げられなかった、オブジェクトの同一性と、そこから考えられるオブジェクト同士の比較、それからオブジェクトの文字列表現について見ていこう。
「Python入門」
Copyright© Digital Advantage Corp. All Rights Reserved.