Up,en

オブジェクトの連結

オブジェクトを、変数の参照機能によって、C/C++のポインタを使った場合のように連結するプログラムを作成してみた。

オブジェクトとして図1のようなクラス型のものを考える。

図1

 

アトリビュートpとcによって前後のオブジェクトと連結している。図1のオブジェクトをコードとして表したものが、以下に示すクラス型Dataである。

 

class Data:

    count = 0

    def __init__(self):

        self.p = 0

        self.c = 0

        self.d = ""

        self.id = Data.count

        Data.count += 1

 

    def print(self):

        print("ID: {0}  Data = {1}".format(self.id, self.d))

 

アトリビュートpとcは、それぞれ直前に生成されたオブジェクト、直後に生成されるオブジェクトを指し示すものである。アトリビュートpあるいはcを、Dictionary型などを用いるために

self.p = {}

あるいは

self.c = {}

などとすれば、複数の親あるいは子と繋ぐことができる。

アトリビュートdにデータ(文字列)を設定し、idにはオブジェクトの通し番号を設定する。クラス型Dataのアトリビュートcountは、クラス型に共通のものとして用意され、idの設定に用いる。メソッドprintは、iddを出力するものである。

オブジェクトの連結を作成するために、出発点を表すp_startと終点を表すp_endを次のように用意する。

 

p_start = Data()

p_end = Data()

p_end.id = -1

p_start.c = p_end

p_end.p = p_start

p_current = p_start

Data.count = 1

 

出発点を表すp_startidは0に設定されている。終点を表すp_endidには−1を設定しておく。初期状態として、p_startの子としてp_endを、p_endの親としてp_startを設定しておく。現在のオブジェクトを示すものとしてp_currentを用意し、p_startを指し示しておく。クラス型Dataのアトリビュートcountの値を1に設定して、以後のオブジェクトの作成の通し番号の準備とする。

データの入力を行うコードを以下のように用意した。

 

while True:

    s = input('Data = ')

    if (s == ""):

        break

    else:

        p_temp = Data()

        p_temp.d = s

        p_current.c = p_temp

        p_temp.p = p_current

        p_temp.c = p_end

        p_current = p_temp

        p_end.p = p_current

 

データは、コンソールに「Data = 」と出された後に、文字列で入力する。何も入力せずにEnterキーのみが押されたところで、入力終了となる。

入力されたデータは、p_tempに作成されたオブジェクトのアトリビュートdに格納され、p_currentのアトリビュートcは新しく作成されたp_tempのオブジェクトを指し示すように設定される。t_tempのアトリビュートpp_currentを指し示すように設定され、アトリビュートcp_endを指し示すように設定される。その後、p_currentは新しく生成されたオブジェクトp_tempを指し示すように設定され、このp_currentp_endのアトリビュートpが指し示すように設定される。

データ入力の終了後、入力されたデータがあれば(Data.count > 1)、最後に入力されたデータから順番に出力されるが、それは以下のコードによって実行される。

 

if Data.count > 1:

    while True:

        p_current.print()

        p_current = p_current.p

        if p_current.id == 0:

            break

 

オブジェクトのアトリビュートidが0であるということは、そのオブジェクトがp_startの指し示すものであることを意味している。

最初の位置p_startまでp_currentが戻れば、次に逆に最初に入力したデータから順番に最後のデータまでが出力される。これは、次のコードによって行われる。

 

    p_current = p_current.c

    while p_current.id != -1:

        p_current.print()

        p_current = p_current.c

 

アトリビュートidの値が−1であることは、最後の位置p_endに達していることを意味している。

以上のコードを1つにまとめると以下のようになる。

=========== サンプルプログラム =================

class Data:

    count = 0

    def __init__(self):

        self.p = 0

        self.c = 0

        self.d = ""

        self.id = Data.count

        Data.count += 1

 

    def print(self):

        print("ID: {0}  Data = {1}".format(self.id, self.d))

 

p_start = Data()

p_end = Data()

p_end.id = -1

p_start.c = p_end

p_end.p = p_start

p_current = p_start

Data.count = 1

while True:

    s = input('Data = ')

    if (s == ""):

        break

    else:

        p_temp = Data()

        p_temp.d = s

        p_current.c = p_temp

        p_temp.p = p_current

        p_temp.c = p_end

        p_current = p_temp

        p_end.p = p_current

 

if Data.count > 1:

    while True:

        p_current.print()

        p_current = p_current.p

        if p_current.id == 0:

            break

 

    p_current = p_current.c

    while p_current.id != -1:

        p_current.print()

        p_current = p_current.c

===================================

 

上のプログラムの実行例を図2に示す。

図2

 

Data = 」と空の文字列を入力した(何もキーを押さず、Enterキーのみを押す)ところでデータの入力が終わり、その後、後から入力したデータから最初のデータまでが表示されて、次に、1番目からのデータから最後までのデータが表示されている。

 

 

Up