検索
連載

[Python入門]リストを継承してスタックを作成するPython入門(2/2 ページ)

以前にリストを利用して作成したスタックを、今度はリストを継承して作成しながら、「is-a」「has-a」「クラスのカスタマイズ」といったことについて見ていこう。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

スタックのカスタマイズ

 このようにして作成したスタックは、必要に応じて、メソッドや特殊メソッドをオーバーライドして、その動作を自分のクラスに適したものに変更できる。以下では幾つか例を見てみよう。

__init__メソッドのオーバーライド

 例えば、__init__メソッドのオーバーライドについて考えてみよう。

 list関数は「反復可能オブジェクトを0個または1個だけ引数に取る」のが仕様だ。

mylist = list([1, 2, 3])  # 1、2、3を要素とするリストを生成
print(mylist)
mylist = list(1, 2, 3# エラー(引数は0個か1個だけ)

list関数の振る舞い

 現在のMyStack3クラスでは__init__メソッドを定義していないので、そのインスタンスを生成する際には基底クラスの__init__メソッドが呼び出され(て、そこにMyStack関数呼び出しに渡した引数が渡され)る。

mystack = MyStack3([1, 2, 3])  # 1、2、3を要素とするスタックを生成
print(mystack)
mystack = MyStack(1, 2, 3# エラー(引数は0個か1個だけ)

MyStackクラスのインスタンス生成時の振る舞い

 だが、前々回に作成したスタックでは、そのインスタンス生成時に次のような振る舞いをしていた。

  • 任意の数の引数をカンマ区切りで渡す
  • カンマで区切られた引数はそれぞれが個別にスタックの要素となる

 「スタックはリスト(の一種)」であることや、tuple関数やset関数などでも反復可能オブジェクトを受け取り、そこから要素を反復的に取り出すのが一般的であるため、現在の振る舞いの方が「よりPythonのオブジェクトらしい」といえるが、ここでは上記の振る舞いとなるように__init__メソッドをオーバーライドしてみよう。

 といっても書かなければならないコードはシンプルだ。

class MyStack3(list):
    def __init__(self, *args):
        # print(args)  # 可変長位置引数を確認したければコメントアウト
        super().__init__(args)
    def push(self, item):
        self.append(item)

インスタンス生成時の振る舞いが前々回と変わらないように修正したコード

 __init__メソッドには可変長引数を受け取るパラメーターを持たせる。このパラメーターには0個以上の引数が「タプル」にまとめられて渡される。以下の表は「MyStack3(……)」呼び出しの引数によってこのパラメーターがどうなるかをまとめたものだ。

MyStack3()呼び出し パラメーターargsの値
MyStack3() ():空のタプル
MyStack3(1) (1,):要素が1つのタプル
MyStack3([1, 2, 3]) ([1, 2, 3],):要素が1つのタプル
MyStack3(1, 2, 3) (1, 2, 3):要素が3つのタプル
MyStack3関数呼び出しの形式とargs

 パラメーターargsはタプル、すなわち反復可能オブジェクトなので、実はこれをそのまま基底クラスの__init__メソッドに渡せば、その要素を使ってリストが作成される。「MyStack3([1, 2, 3])」という呼び出しならタプルには要素が1つだけなので、「[1, 2, 3]」というリストがそのままスタックの要素となるし、「MyStack3(1, 2, 3)」ならタプルの要素は3つあるので、1、2、3を個々の要素とするスタックが作られるようになるわけだ。

Copyright© Digital Advantage Corp. All Rights Reserved.

前のページへ |       
[an error occurred while processing this directive]
ページトップに戻る